Optimizing Webpack build performance
One question that arises frequently is how to improve the performance of our web applications. I use to think that we always must start from the ground and dig in what can be leading to a slowness in our application. In this article we are going to talk specifically about Webpack's build performance.
There are two modes in which we commonly work
- Development mode
- Production mode
Each of these modes have its own needs, so for example, it's very common that we use webpack hot reloading in development mode to avoid redeploying the application's server every time we change something at the codebase. Also, it's very common that we minify our assets only at production, as we may want to be able to debug our applications in development mode.
Most part of these features are enabled by plugins, one of the most important things that webpack brought to us, because they enable the extensibility of webpack's basic functionalities, and it's very important to know what we can do with every plugin.
When talking about webpack performance, there are some basic things that appear
- Cache your modules
- Split your code in two parts: Vendor and Application
Cache your modules
This is something very obvious and not only used inside the build. Cache is one of the first things that comes into mind when we try to improve the performance of any application, and it is done not only at the build.
There are a few options to cache your modules
- Official Caching documentation
This will solve some of the problems of your application after the first build, however I will not focus into this approach.
The term DLL stands for Dynamically Linked Library, and is a Windows feature that is used to optimize build times and improve caching for users by allocating the code that is used infrequently into separate bundles.
This approach suggest to split you code in two parts:
Vendor will have the code that belongs to libraries that won't change too much in time, e.g React, Redux, Moment, Lodash. Indeed you expect that code not to change very frequently.
Application will have the code written by you/your team.
This way, the code that changes more frequently will be separated from the code that does not. This will improve the build and cache time. That is why I didn't focus on the former approach.
As described in the Webpack's official documentation:
DllReferencePluginprovide means to split bundles in a way that can drastically improve build time performance.
I will use this React Boilerplate that is a very simple react application that uses the following libraries:
The configuration of the DllPlugin and DllReferencePlugin has two steps.
- Create the file webpack.vendor.config.js for DllPlugin
- Reference your vendor file from your webpack.config.js using DllReferencePlugin
Create vendor file
This file will contain a small configuration for compiling the vendor libs.
The most important thing here is the entry point. The word vendor can have other name if desired and will contain an array with the name of the libraries referenced in the package.json file.
The output of this webpack build will be a file called vendor.build.js and a file called vendor-manifest.json.
As explained by Robert Kinght in his article:
This build generates a JSON manifest, which is a mapping between the file paths of modules inside the bundle and the integer IDs that each module has been assigned. This manifest is used by your application bundles to determine whether a library bundle provides a particular module and if so, how to access it from another bundle.
The file that will be imported in your html will be vendor_lib.js and its name is configured at output['library']. In this case we chose [name]_bundle.js.
Again, file names can be chosen as you like
Reference your vendor file
From your file webpack.config.js you have to reference the recently created file vendor-manifest.json.
As you can see, at lines 27–30 I included the DllReferencePlugin. There is no magic in that.
The build time is reduced almost to half as you can see in the images below
If images are not clear, the build without DllPlugin took 10,5 seconds and the build with DllPlugin took 6,4 seconds.
If you consider that this is a very small application, the improvement was very good. Think about reducing your build time from 30 seconds to 10–15.
The DllPlugin and DllReferencePlugin provide means to split bundles in a way that can drastically improve build time…webpack.js.org
Thanks, and hope it helps! :)