Keep track of the bundle size
To monitor your app size, use webpack-dashboard
during development and bundlesize
on CI.
webpack-dashboard
webpack-dashboard
enhances webpack output with sizes of dependencies, progress and other details. Here’s how it looks:
This dashboard helps to track large dependencies – if you add one, you’ll immediately see it in the Modules section!
To enable it, install the webpack-dashboard
package:
npm install webpack-dashboard --save-dev
And add the plugin into the plugins
section of the config:
// webpack.config.js
const DashboardPlugin = require('webpack-dashboard/plugin');
module.exports = {
plugins: [
new DashboardPlugin(),
],
};
or using compiler.apply()
if you’re using an Express-based dev server:
compiler.apply(new DashboardPlugin());
Feel free to play with the dashboard to find the probable places for improvement! For example, scroll through the Modules
section to find what libraries are too large and could be replaced with smaller alternatives.
bundlesize
bundlesize
verifies that webpack assets don’t exceed the specified sizes. Integrate it with a CI to get notified when the app becomes too large:
To configure it:
Find out the maximum sizes
Optimize the app to make it as small as possible. Run the production build.
Add the
bundlesize
section intopackage.json
with the following content:
// package.json
{
"bundlesize": [
{
"path": "./dist/*"
}
]
}
- Execute bundlesize with
npx
:npx bundlesize
This will print the gzipped size of each file:
PASS ./dist/icon256.6168aaac8461862eab7a.png: 10.89KB
PASS ./dist/icon512.c3e073a4100bd0c28a86.png: 13.1KB
PASS ./dist/main.0c8b617dfc40c2827ae3.js: 16.28KB
PASS ./dist/vendor.ff9f7ea865884e6a84c8.js: 31.49KB
- Add 10-20% to each size, and you’ll get the maximum sizes. This 10-20% margin would let you develop the app as usual while warning you when its size grows too much.
Enable bundlesize
- Install the
bundlesize
package as a development dependency:
npm install bundlesize --save-dev
- In the
bundlesize
section in thepackage.json
, specify the concrete maximum sizes. For some files (e.g., images), you might want to specify the maximum size per file type, not per each file:
// package.json
{
"bundlesize": [
{
"path": "./dist/*.png",
"maxSize": "16 kB",
},
{
"path": "./dist/main.*.js",
"maxSize": "20 kB",
},
{
"path": "./dist/vendor.*.js",
"maxSize": "35 kB",
}
]
}
- Add an npm script to run the check:
// package.json
{
"scripts": {
"check-size": "bundlesize"
}
}
- Configure the CI to execute npm run check-size on each push. (And integrate
bundlesize
with GitHub if you’re developing the project on it.)
That’s it! Now, if you run npm run check-size
or push the code, you’ll see if the output files are small enough:
Or, in case of failures:
Analyze why the bundle is so large
You might want to dig deeper into the bundle to see what modules take space in it. Meet webpack-bundle-analyzer
:
webpack-bundle-analyzer
scans the bundle and builds a visualization of what’s inside it. Use this visualization to find large or unnecessary dependencies.
To use the analyzer, install the webpack-bundle-analyzer
package:
npm install webpack-bundle-analyzer --save-dev
Add a plugin to the webpack config:
// webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin(),
],
};
and run the production build. The plugin will open the stats page in a browser.
By default, the stats page shows the size of parsed files (i.e., of files as they appear in the bundle). You’ll likely want to compare gzip sizes since that’s closer to what real users experience; use the sidebar on the left to switch the sizes.
Here’s what to look for in the report:
Large dependencies : Why are they so large? Are there smaller alternatives (e.g., Preact instead of React)? Do you use all the code it includes (e.g., Moment.js includes a lot of locales that are often not used and could be dropped)?
Duplicated dependencies : Do you see the same library repeating in multiple files? (Use, e.g., the optimization.splitChunks.chunks option – in webpack 4 – or the CommonsChunkPlugin – in webpack 3 – to move it into a common file.) Or does the bundle have multiple versions of the same library?
Similar dependencies : Are there similar libraries that do approximately the same job? (E.g. moment and date-fns, or lodash and lodash-es.) Try sticking with a single tool.
Conclusion
Use
webpack-dashboard
andbundlesize
to stay tuned of how large your app isDig into what builds up the size with
webpack-bundle-analyzer