Using tools like Webpack we can enable code splitting and only load our application code asynchronously when required.
Example in the context of a react application with react-router.
Load initial page.
-> go to new route
---> webpack loads in the component file required asynchronous.
Webpack waits until the code is required in order to initiate the request.
My question is, once the base application code load, can we start loading the rest of the code, even before the user initiates the transition to the new route?
My view is that will prevent the user from waiting for the webpack chunk to download.
-> Load initial page
--> user sitting idle or browsing on home page
----> Start loading application code for rest of the application
---> user goes to new route (faster UX because code has already download in the background)
I hope this makes sense
Code splitting allows you to break up the monolithic bundle into various smaller bundles. You can then load the bundles in parallel or implement lazy loading, delaying download of certain code until a user needs it.
Code-splitting is splitting the bundle file into chunks based on the user's needs or what the user is interested in seeing. This idea brings about a decrease in the website's load time since users will need to download a smaller bundle file, giving users a better experience.
Code-Splitting is a feature supported by bundlers like Webpack, Rollup and Browserify (via factor-bundle) which can create multiple bundles that can be dynamically loaded at runtime.
Code splitting is one of the most compelling features of webpack. This feature allows you to split your code into various bundles which can then be loaded on demand or in parallel.
Yes you can achieve this. I will show one of the possible solutions.
Firstly let's create backgroundLoader
for queuing required chunks:
const queue = [];
const delay = 1000;
let isWaiting = false;
function requestLoad() {
if (isWaiting) {
return;
}
if (!queue.length) {
return;
}
const loader = queue.pop();
isWaiting = true;
loader(() => {
setTimeout(() => {
isWaiting = false;
requestLoad();
}, delay)
});
}
export default (loader) => {
queue.push(loader);
requestLoad();
}
This function will load your chunks in background with 1 second delay (you can tweak it - for example start popping queue after for example 5 second or shuffle array of chunks).
Next you must register your require.ensure
in queuing function backgroundLoader
:
import render from './render'; // not relevant in this example
import backgroundLoader from './backgroundLoader';
let lightTheme = (cb) => {
require.ensure([], () => {
cb(require('./themeA.css'));
}, 'light');
}
let darkTheme = (cb) => {
require.ensure([], () => {
cb(require('./themeB.css'));
}, 'dark');
}
let pinkTheme = (cb) => {
require.ensure([], () => {
cb(require('./themeC.css'));
}, 'pink');
}
backgroundLoader(lightTheme);
backgroundLoader(darkTheme);
backgroundLoader(pinkTheme);
export default (themeName) => { // router simulation
switch(themeName) {
case 'light':
lightTheme(render);
break;
case 'dark':
darkTheme(render);
break;
case 'pink':
pinkTheme(render);
break;
}
};
Once you require your chunk in switch
statement you pass render
function containing resolve function. In backgroundLoader
this function will be empty resulting only loading chunk to head
of your app.
Full code for this example you can see on WebpackBin (you can check network to see how chunks are loaded in background)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With