Divide and conquer! Lazy loading for your SPA

Get a performance boost with just Webpack

Martin Callegari
Wolox

--

“How in the world is this so slow? I’m just using 100 components. Come on the browser, do your thing!” Sounds familiar? Well, it’s time to try a performance boost.

If you are a web developer, chances are you are using Webpack as your module bundler, and probably you don’t know what lazy loading is.

What is lazy loading?

I know what you are thinking: “Lazy is not fast, those are quite opposite”. You are not wrong on semantics but there’s another way to see it. Let’s see what the definition for lazy loading is, according to Webpack:

Lazy, or “on demand”, loading is a great way to optimize your site or application. This practice essentially involves splitting your code at logical breakpoints, and then loading it once the user has done something that requires, or will require, a new block of code.

In other words, you can split your code in any way you want (i.e. components), and the browser will only load the code needed for your app to work. This sounds really awesome!

Why do I need this?

That’s a simple question. Boost your performance! With lazy loading, only the needed code will be loaded and doing so, your initial loading will be faster (because you will load much less code) and your overall speed will be much faster being on demand.

I also like how the code is being bundled when lazy loading is applied. Without it, you’ll probably have an HTML file, a CSS and only one giant JS.

How can I accomplish this?

First of all, you’ll need Webpack and with it, Babel and a couple of plugins.

npm i -D dynamic-import-webpack syntax-dynamic-import

Now that we got everything installed, we need to add them to the .babelrc, our Babel configuration file.

{  "plugins": [    ...    "dynamic-import-webpack",    "syntax-dynamic-import"  ],  "presets": [    ["env", {      "targets": [        "last 2 versions", "safari >= 7", "not ie < 9"      ]    }]  ]}

Of course, this is just the needed Babel configuration to run your application. Feel free to add whatever plugin/preset suits your needs.

You are probably thinking you’ll need to code in a different way. The truth is, you won’t need to. The only thing that will change is how you import your code.

Show me some code!

React and Vue are amazing frameworks and no matter which one you are using, there’s a simple way to decide how to split our code that’s shared between the two. Components! Component-based code splitting is the best strategy you can use with this frameworks.

React async route with react-loadable

In the code above, we use react-loadable to get our async route to work (you can also use it for components that are not necessary routes), and it adds some functionalities, like show a loader when the component is being requested and timeout management.

Vue async component

For Vue, the component can be requested with just the dynamic import function and registered to the instance just like is shown above. This is just for components, but for routes is the same, just add the component as the route component in your router configuration.

By all means, we can’t forget about Angular since we can also do this changing only configuration:

After running our project’s build, we can now see that there are different files created that, if you were not using lazy loading, weren’t there before.

React app with lazy loading

There, we are separating the async route of our app from the main chunk of code. We now have our chunks the way we want, so how’s this going to work? Let’s check the Network view in our browser console as we load the view

Chrome requesting our components only used in this view

Those numbered JS files are our async components being loaded only when needed. That requests are Vue components without any package that helps us like react-loadable , that’s why they are not hashed like the image above (the latest being a React App)

Can we come up with any conclusions? Maybe, if you are not using async components, give it a shot! Certainly, here I showed you how to separate into async routes and components, but you can also separate your vendor files into another chunks. That way you can minimize even more the size of your app, as well as bring a lot of little performance improvements with this code splitting technique.

--

--

Martin Callegari
Wolox
Writer for

I'm a Software Engineering Student and Front-End web developer. Love dogs, gaming, and programming.