1. 19
    Analyze a Production JavaScript Bundle with webpack-bundle-analyzer
    5m 52s

Analyze a Production JavaScript Bundle with webpack-bundle-analyzer

Andy Van Slaars
InstructorAndy Van Slaars
Share this video with your friends

Social Share Links

Send Tweet
Published 5 years ago
Updated 5 years ago

Bundle size has a huge impact on JavaScript performance. It's not just about download speed, but all the JavaScript we ship to the browser needs to be parsed and compiled before it can be executed. Keeping our bundle in check can be difficult, but it's much easier when we can see where the bloat is coming from. In this lesson, we'll add the webpack-bundle-analyzer plugin to inspect the output of our production build.

Instructor: [00:00] With all the npm modules readily available to us, it's important to keep an eye on our JavaScript bundles, and make sure that we don't add too many things and end up with a bloated bundle that has to be shipped down to a browser. We can use a webpack plugin to analyze our bundles. Let's install that now.

[00:16] We'll run npm i, passing it the --d flag to save as a dev dependency, webpack-bundle-analyzer. With that installed, let's wire it up.

[00:33] We're going to do this in our webpack.config.prog file. We want to analyze the bundles in our production builds, because webpack is going to optimize builds differently between dev and production.

[00:44] Production is what's going to go to our customers. That's what's going to have to be parsed by the browser, and that's what's going to impact our performance in a production setting.

[00:52] We'll start at the top of this file. We're going to pull bundle-analyzer-plugin, [inaudible] require for the webpack-bundle-analyzer package. With that imported, I'm going to drop down into my configuration and I'm going to add a plugins entry here. That's going to take an array. I'm going to pass in a new bundle-analyzer-plugin instance. I'll save that.

[01:28] With that in place, I'm going to drop into the terminal and I'm going to do a production build with npm run build.

[01:38] You'll notice that in our terminal that it tells us that the webpack-bundle-analyzer has started. It's giving us an address, and it's telling us to use Ctrl-C to close it. It's actually running a server. If we look at the browser, it's serving up this page that breaks down our bundle. If we hover over each of these sections, we'll see different output.

[01:59] If we look at the entire bundle by hovering over the top here, we'll see that our stat size is 136K, our parse size is 120, and our gzip size is 38. The parse size is highlighted here, and this is the one that's going to impact our performance.

[02:17] Gzip files are a good idea. It's going to save on bandwidth, but when it gets to the browser, ultimately, the browser is going to have to parse 120K, which is not terrible, but that's the size to keep an eye on.

[02:29] If we look at the breakdown, it's going to show us our source directory where our files are. We have app.js, which is a little under 4K. Styles.css is 556 bytes, index.js is very small, and then we have in the node_modules, react-dom, react, and then we can see the child libraries that those use.

[02:56] If we come over here to the right, we'll see this little sidebar. If we end up with a lot of libraries, we can search for modules, too. We can come in here and we can search for react, and it'll highlight anything that has react in its name. We can zoom in on those.

[03:13] If we want to keep this open on the side, we can pin it here. We can shrink it down a little bit. We can also use our scroll wheel if we want to zoom in and out. We can do that.

[03:25] As our application gets more complex, and our bundle has more and more parts to it, we'll be able to keep an eye on the size and then focus in on the things that maybe add additional bloat that we don't want. If a library is making your bundle huge, then this will give you the information you need to mitigate that.

[03:41] Let's go back to our terminal. We'll see that this is still running. It's going to hang this process. I'm going to Ctrl-C to exit that. This isn't necessarily the behavior I want. I'd like this to open in a browser, because it's good to have it visible, but I don't want it to be served from that process so that the process hangs. I just want to do a build, have a clean exit, and also see that dev.

[04:01] To do that, I'm going to come up here. This bundle-analyzer-plugin constructor will take an options object. I can come in here, and I can pass it in analyzer mode. We're going to pass it the value static.

[04:17] I'm going to save this, and then back in the terminal, I'm going to do an npm run build again. This is going to open that output in the browser, but you'll see this time it's a file address. If I come back and look at my terminal, it exits. It's not sitting there running on a server.

[04:39] If we take a look at our dist directory, we'll see that this is where that output went. We have a report.html file that gets put into our dist directory that gives us our bundle analyzer report with all the same things we saw when it was running on a server.

[04:57] If I wanted to generate the report but not automatically open it in a browser, I can come in here and I can add the open analyzer flag, and I can set that to false. If I wanted to change the default output name of report.html, I could come in here and I could add the report filename option. I can just pass that as string. We'll call that bundle-sizes.html.

[05:26] If I save that and I do an npm run build again, we'll see that it doesn't jump to the browser, because nothing was opened. Now I get bundle-sizes.html as my output, but if I wanted to check them out, I can just run an open dist/bundle-sizes.html. We'll see that our report still works fine in a browser.

Alex Wardi
Alex Wardi
~ 5 years ago

Thanks for the excellent rundown on webpack, Andy!

I ran into something quite interesting regrading the webpack-bundle-analyzer plugin section. Webpack will automatically use the concatenateModules optimization, which may obscure the problem areas when viewing the analyzer html page.

My largest chunk was showing something like index.js + <n> modules (concatenated) on the analyzer HTML page. After altering my webpack.config.prod.js file to skip module concatenation, the analyzer page showed the full output for the chunk. Here's what I did:

module.exports = merge(baseConfig, {
    mode: 'production',
    stats: 'minimal',
    plugins: [new BundleAnalyzerPlugin({
        analyzerMode: 'static'
    })],
    optimization: {
        concatenateModules: false // Add this flag to view all modules. Should be used for debugging only. Remove for actual prod build
    }
});

Hopefully this helps someone else in the future. Thanks again, great lesson!!

Andy Van Slaars
Andy Van Slaarsinstructor
~ 5 years ago

Thanks for sharing, Alex. This is a great tip!

Markdown supported.
Become a member to join the discussionEnroll Today