Learn webpack in Under 10 Minutes
By: Harsha Vardhan
Tags: JavaScript, Software Development, Front End Development, Webpack, Programming

Optimizations — Code Splitting

Code splitting or lazy loading is an optimization technique to avoid large bundles. It also avoids dependencies duplication. By using this mechanism we load a piece of code on demand, e.g., whenever a user clicks a button, when the route changes, etc. The piece of code that is split is known as a chunk.

There is a limitation in webpack that the maximum file size of the initial bundle of the application should be less than 244 KiB. There are three ways to achieve code splitting in webpack:

Having multiple entry points Using optimization.splitChunks Dynamic imports

The first method works well for smaller projects but isn’t scalable in a complex one. We specify multiple entry points in our webpack configuration file.

Using optimization.splitChunks

There are times where we use a lot of dependencies in our application. For example, let’s use a popular package for dates: Moment. I chose this package because it is a bit heavy in size. Let’s install it and then include it in our index.js file and run our build command.

npm install moment

Moment will be successfully installed. Now let’s import it into our index.js file.

import moment from 'moment'

Now let’s run our build command.

npm run build

You’ll get this warning message in the terminal:

Oversized main.js file

So how do we solve this? It’s simple. Let’s add a key named optimization and another property within it called splitChunks like this:

You’ll find that the size of the entry point is considerably reduced.

Reduced entry point file size

Dynamic imports

Dynamic imports are used to load code conditionally. This approach is widely used in React and Vue. We can either load code based on user interaction or based on the route change.

To demonstrate, let’s add a button to our page, which on click fetches a list of posts for us. The code for this fetching logic is present in a separate file. It is imported dynamically inside our index.js file.

Let’s have a fetch API call alone in a file named api.js inside the source folder. Here, we export a function that makes a request to a public API and returns a response.

Let’s create a button in our index.html file with an id property set to btn .

<button id="btn">Click me to load</button>

Inside our index.js file, let’s do dynamic importing by using a function to import our api.js file.

const getTodos = () => import('./api')

Also, let’s add this logic to log the fetched data by adding this at the end of the file.

const btn = document.getElementById('btn'); btn.addEventListener('click', () => {

getTodos().then(({fetchTodos}) => {

fetchTodos().then(resp => console.log(resp))

})

})

This code snippet calls the getTodos function, which imports the file for us. Then after importing it, we destructure the fetchTodos property from it, call the function, and then log the response on its success.

Let’s build our files, run our server, and make sure to open the dev tools and keep the network tab open. You’ll find that on click, there is a new JS file that is dynamically loaded.

Dynamic imports

The 0.main.js is the file that was loaded dynamically. If you want this file to have a readable name, you just need to add a comment during dynamic import like this:

const getTodos = () => import( /* webpackChunkName: "postsAPI" */ './api')