27 June 2022
Svelte is gaining a lot of traction these days. It is easy to implement and learn. The main reason i have started using Svelte is that it is not opinionated. Mostly, I just have to write what actually is required - HTML, CSS and JS and do not worry about the optimizations.
But, as the application grows the end users of any application has to pay the price. The hidden cost of downloading mega chunks of JS and CSS resources. We can optimize this via using extra efficient systems and techniques in place e.g. CDN, Browser Cache, Uglify/Minify
are a few basic optimizations techniques. As you see, It does not reduce the actual amount of code that is being parsed on the browser.
Type | Transferred | Actual Size |
---|---|---|
js | 39.59 KB | 100.63KB |
The Actual Size is what the browser has to parse. This in itself is a bottle neck in old/low-end devices. JS is everywhere now and We must optimize the experience for everyone.
We can squeeze the air out of a pillow with a vacuum device. Even after that, there is still a piece of mass that requires space in our storage.
We can further reduce the amount of code with help of dynamic imports and keep our application as lean as possible. The idea behind the code splitting is simple - Load only the part of application code which is required to render the particular route the user is visiting.
The code splitting of the route resources can further be bifurcated into above the fold and below the fold content (there is no straight way of doing it).
I have a route based application, where each route loads an async Component
.
const routes =[{path:'/svelte-code-splitting',name:'Svelte Code splitting',component:()=>import('./markdown/code-splitting-svelte.md'),},];
To load the component async and do something while it loads, I did write a util function which handles the loading and returns the default export of the es
module.
constgetComponent=async(module)=>{const component =(await module).default;return component;};
The above function is called for each route.
{#eacharticles asarticle}<Routepath={article.path}>{#awaitgetComponent(article.component()) then Component}<Component/>{/await}</Route>{/each}
Notice the artilce.component
is a function which is evoked when the route is matched.
This is the bare minimum code which is required for creating dynamic chunks during the build processes.
rollup.config.js
output:{format:'es',name:'thoughts',dir:'thoughts/dist/js',}
format
for dynamic chunks is “es” instead of iife. A directory path to save the chunks is provided as dir
.
index.html
<scriptsrc="/dist/js/thoughts.js"type="module"></script>
The main chunk has to added as type=“module”
Chunks are create with chunkName-[hash].js
This can be configured with chunkFileNames
property in rollup.config.js
chunkFileNames:(chunkInfo)=>{return`htmlContent#123;chunkInfo.name}.js`;},
Inside the index.html
we need to add only the the main bundle i.e. thought.js
in our case. It has all the information of the chunks that has been created. It loads them in sync to boot the application.