- Created minimal, tree-shaken vendor bundles: * Core bundle (3KB): Always loaded utilities and theme management * Map bundle (255KB): Leaflet + plugins, loaded only for map pages * Chart bundle (205KB): Chart.js, loaded only for chart pages * Date adapter (50KB): Chart.js time scale support - Total optimized size: 513KB JS + 12KB CSS (was 547KB + 17KB) - Implemented conditional loading via VendorLoader utility - Bundle loading triggered by LiveView hooks when needed - Fixed Chart.js date adapter dependency loading - Eliminated unused JavaScript from being sent to browsers - Created separate esbuild configs for each optimized bundle Performance improvements: - Map pages: Core + Map bundles = 258KB (47% of original) - Chart pages: Core + Chart + Adapter = 258KB (47% of original) - Other pages: Core bundle only = 3KB (0.5% of original) - Reduced initial page load by 94% for non-map/chart pages 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
34 lines
3.4 KiB
JavaScript
34 lines
3.4 KiB
JavaScript
// Core utilities bundle
|
|
|
|
/* Topbar */
|
|
/**
|
|
* @license MIT
|
|
* topbar 3.0.0
|
|
* http://buunguyen.github.io/topbar
|
|
* Copyright (c) 2024 Buu Nguyen
|
|
*/
|
|
(function(window,document){"use strict";function repaint(){canvas.width=window.innerWidth,canvas.height=5*options.barThickness;var ctx=canvas.getContext("2d");ctx.shadowBlur=options.shadowBlur,ctx.shadowColor=options.shadowColor;var stop,lineGradient=ctx.createLinearGradient(0,0,canvas.width,0);for(stop in options.barColors)lineGradient.addColorStop(stop,options.barColors[stop]);ctx.lineWidth=options.barThickness,ctx.beginPath(),ctx.moveTo(0,options.barThickness/2),ctx.lineTo(Math.ceil(currentProgress*canvas.width),options.barThickness/2),ctx.strokeStyle=lineGradient,ctx.stroke()}var canvas,currentProgress,showing,progressTimerId=null,fadeTimerId=null,delayTimerId=null,options={autoRun:!0,barThickness:3,barColors:{0:"rgba(26, 188, 156, .9)",".25":"rgba(52, 152, 219, .9)",".50":"rgba(241, 196, 15, .9)",".75":"rgba(230, 126, 34, .9)","1.0":"rgba(211, 84, 0, .9)"},shadowBlur:10,shadowColor:"rgba(0, 0, 0, .6)",className:null},topbar={config:function(opts){for(var key in opts)options.hasOwnProperty(key)&&(options[key]=opts[key])},show:function(handler){var type,elem;showing||(handler?delayTimerId=delayTimerId||setTimeout(()=>topbar.show(),handler):(showing=!0,null!==fadeTimerId&&window.cancelAnimationFrame(fadeTimerId),canvas||((elem=(canvas=document.createElement("canvas")).style).position="fixed",elem.top=elem.left=elem.right=elem.margin=elem.padding=0,elem.zIndex=100001,elem.display="none",options.className&&canvas.classList.add(options.className),type="resize",handler=repaint,(elem=window).addEventListener?elem.addEventListener(type,handler,!1):elem.attachEvent?elem.attachEvent("on"+type,handler):elem["on"+type]=handler),canvas.parentElement||document.body.appendChild(canvas),canvas.style.opacity=1,canvas.style.display="block",topbar.progress(0),options.autoRun&&function loop(){progressTimerId=window.requestAnimationFrame(loop),topbar.progress("+"+.05*Math.pow(1-Math.sqrt(currentProgress),2))}()))},progress:function(to){return void 0===to||("string"==typeof to&&(to=(0<=to.indexOf("+")||0<=to.indexOf("-")?currentProgress:0)+parseFloat(to)),currentProgress=1<to?1:to,repaint()),currentProgress},hide:function(){clearTimeout(delayTimerId),delayTimerId=null,showing&&(showing=!1,null!=progressTimerId&&(window.cancelAnimationFrame(progressTimerId),progressTimerId=null),function loop(){return 1<=topbar.progress("+.1")&&(canvas.style.opacity-=.05,canvas.style.opacity<=.05)?(canvas.style.display="none",void(fadeTimerId=null)):void(fadeTimerId=window.requestAnimationFrame(loop))}())}};"object"==typeof module&&"object"==typeof module.exports?module.exports=topbar:"function"==typeof define&&define.amd?define(function(){return topbar}):this.topbar=topbar}).call(this,window,document);
|
|
|
|
/* Theme utilities */
|
|
window.ThemeUtils = {
|
|
setTheme: function(theme) {
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
localStorage.setItem('theme', theme);
|
|
},
|
|
|
|
getTheme: function() {
|
|
return localStorage.getItem('theme') || 'light';
|
|
},
|
|
|
|
initTheme: function() {
|
|
const savedTheme = this.getTheme();
|
|
this.setTheme(savedTheme);
|
|
}
|
|
};
|
|
|
|
// Auto-initialize theme
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', () => window.ThemeUtils.initTheme());
|
|
} else {
|
|
window.ThemeUtils.initTheme();
|
|
}
|