I have recently had the opportunity to get my hands dirty with Webpack bundle analyzer and have observed a shortage of comprehensive resources available on the web. It appears that this tool is often encountered sporadically, leading us to relearn its features each time we engage with it.
In this post I would like to extend an invitation to share the insights I have gained from my experience and provide a more thorough understanding of its functionality.
Hey! for more content like the one you're about to read check out @mattibarzeev on Twitter đ»
Launching the analyzer
I assume you can find your way in installing the bundle-anayzer webpack plugin, as described here, but if youâre using the Create React App it might not be that trivial.
The way I found to do that is to build the application with --stats
param and then use the result json file to generate the bundle-analyzer treemap.
You can sum it up all in a single npm script that goes like this:
"scripts": {
. . .
"profile": "npm run build -- --stats && npx webpack-bundle-analyzer ./build/bundle-stats.json"
},
Letâs see how it looks on a sample React application:
We can clearly see 2 main JS bundles and another small âruntimeâ one. The âruntimeâ bundle is for supporting code splitting, so we will focus on the 2 main ones:
- build/static/js/2.ba16a06d.chunk.js
- build/static/js/main.7a341cc4.chunk.js
TIP: It is important to mention that when you launch the analyzer it is better to make sure that Webpack runs in âproductionâ mode, and generates optimized bundles (this should be the default case, but you know⊠). This in order to get the closest simulation to what happens in production.
Analyzing you bundles
In order to start analyzing your bundles you should get a better understanding of the tool youâre about to use. Letâs explore it together -
We can clearly see the 2 bundles which make our application. Webpack, as part of its optimization, divides the code into 2 chunks - one is the chunk for 3rd party vendors such as React, Mobx etc., and the other chunk is the actual application code.
- 2.ba16a06d.chunk.js - 3rd party vendors
- Main.7a341cc4.chunk.js - Application code
If you click on an area in the Treemap it will attempt to focus on that area and enlarge it. Using the mouse wheel will also zoom in and out.
TIP: The Treemap is a Canvas based UI, and as such trying to find modules in it using the native browserâs âfindâ will not help much, but there are other solutions for that. Keep reading⊠;)
Inspection Sidebar
On the top-left corner there is a small button that when clicked, opens up the inspection sidebar. Letâs open it up and pin it so it wonât get closed each time (which is super annoying⊠just saying):
The Treemap sizes
We start at the top and see that there are 3 modes of Treemap size - Stat, Parsed and Gzipped. What does each mean?
Stat - Stat sizes are fetched from the webpack stats object directly, and use the actual source code of your modules as-is and report the size before minification or gzip.
Parsed - Parsed sizes are calculated by reading the actual compiled bundle files and making a link back to the modules from the webpack stats file. So if you use a minifier, such as UglifyJS, the parsed size shows you the size after minification.
Gzipped - gzip sizes are calculated by reading the actual compiled bundle files and running gzip for each one of the module sources separately. Thus the gzip size shows you the size after minification and gzip, but it isn't a 1-to-1 mapping with the actual file sizes as gzipping each module separately yields less "wins" in terms of compression as the separate sources have less opportunities for gzip to compress together.
(These explanations are taken from a response in this enlightening GitHub thread)
If you change the size mode youâre in you will see an immediate effect in 2 places - in the chunks size at the bottom of the sidebar and in the Treemap itself.
The sizes will usually go like this:
Stat > Parsed > Gzipped
(>
acts as greater-than here)
Sometimes the âStatâ size mode will give more information on the content of each package, or in other words, will better indicate what modules are bundled from a certain package.
To improve the analysis even further we can check the âShow content of concatenated modulesâ checkbox (right below the sizes mode) so that we can see what modules are getting concatenated.
For example, letâs take the application bundle and see the difference side-by-side:
Once you have a more detailed overview of what your bundle includes you can start making better decisions on how to optimize it.
Filter to initial chunks
Though not relevant to our current application example, since we have a single entry file for Webpack, sometimes Webpack has more than a single entry point. In that case you will be able to filter on the entry point which interests you and drill down to its chucks. Moving on.
Search modules
Remember when I told you that you cannot use the browser native âfindâ to locate modules youâre interested in? Well, this is where the âsearch modulesâ come in handy. You just place your regex and the Treemap will filter the module or package youâre looking for.
It does more than that - it will show you where this module is used in the different chucks, and the sizes in each place. Letâs try it with âmobxâ:
What happens in the Treemap is even cooler. See how all the places where Mobx is found are painted in red:
This can help in cases where you would like to take a 3rd party like, say, Lodash which may be scattered in different chunks and extract it so it wonât be bundled in each chunk - you will see that before extracting it there are many âRedâ patches in Treemap and afterwards it will reside in a single place.
Show chunks
At the bottom of the sidebar we have the chucks size, where we see all the chunks in total and then each by itself:
We can select just certain chunks to focus on them.
Optimization demo
Letâs take a simple case to show how the bundle-analyzer can help us with optimizing one of our chunks.
Iâm looking at the chuck which holds the mobx-react
package, and inspect its size:
As you can see in the tooltip, upon hovering the package, its parsed size is 9.27KB. Letâs see if we can reduce that.
Iâm going to use mobx-react-lite for that. Iâm installing it and changing every place in the code which uses mobx-react into the lite version. Here is the result after the change was made:
As you can see the change reduces mobx-react parsed footprint on the bundle to 4.14KB (more than 50%), and the bundle-analyzer helps us see that right away.
Wrapping up
The bundle-analyzer is a great tool to gain better understanding on what goes on in your application bundles, and also a tool to check the implications of your bundle optimizations.
A variation of it can also be found in Googleâs Lighthouse devtool, and you can inspect your production bundles and also see the amount of unused code, etc.
Hey! for more content like the one you've just read check out @mattibarzeev on Twitter đ»
Top comments (2)
This is very usefull. You can also use resolutions in the package.json file to force a package version across peer dependencies, but use caution when using these techniques because unintended side effects can occur.
ĐĄongratulations đ„ł! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up đ