Getting the most out of Webpack(er), Part 1

Diagnosing your setup with Webpack Bundle Analyzer

If you’ve done any front-end work over the past couple years, Webpack likely needs no introduction. It’s the industry-standard module bundler and build tool for JavaScript codebases of all sizes.

In a Rails project, Webpack can replace a portion of the functionality that has traditionally been handled by the Asset Pipeline, and the Rails community has enthusiastically embraced the shift. Rails’s flirtations with Webpack are coming to a head in the next major Rails version, with the Webpacker gem set to become the default JavaScript compiler for Rails 6.

At Flatiron School, we’re already using Webpacker to manage all of the JavaScript powering Learn.co, from the assignments app to the in-browser IDE to the lights on every lesson page. The gem provided an ideal entry point for migrating away from our prior Browserify/Gulp-based setup, as it ships with ready-to-rock Rails view helpers and sensible, production-ready defaults.

However, Webpacker didn’t ship with a primer on performance pitfalls to watch out for when Webpackifying a large, legacy code-laden monolith, and, well, we ran into a few.

Running into performance pitfalls.

But fear not; our pain can be your gain. In the second blog post in this series, we’ll explore some of the ways in which our build tools, legacy code, and naïve Webpack setup conspired to bloat our JavaScript bundles and kept Learn.co from reaching peak performance. But first, let’s talk about the tool we use to identify problem areas in our Webpack output.

Webpack Bundle Analyzer

Look at it.

The Webpack Bundle Analyzer plugin is one of several options for visualizing or otherwise introspecting on the actual chunks of code output by Webpack. It’s a great tool for manually checking whether your myriad Webpack configuration options and plugins are set up correctly and performing the expected transformations upon your code. It also just looks really freaking cool:

Analyzing some bundles!

The code snippets in this blog are from our Webpacker config¹, but it should be trivial to translate them to a vanilla Webpack setup. Gotta love leaky abstractions!

Setup

First off, add the package to your project:

yarn add webpack-bundle-analyzer

Next, import and initialize the plugin in one of the environment-specific configuration files or in the base environment.js file:

Most examples showing how to use the Bundle Analyzer plugin have it being used in development mode, but we’ve found that it actually works best in production mode. Now, that’s definitely not to suggest that you should leave the plugin active when deploying an app to production. The plugin adds quite a bit of overhead to a build, and it’s definitely not necessary (or even useful) in a live production build. However, by running Webpack locally in production mode, the bundles displayed in the analyzer will be a much more accurate representation of what we’re actually shipping off to users. Vendor dependencies like React will be much smaller, as the production build removes a ton of helpful but development-only cruft, and, as a bonus, the analyzer will display three different sizes for each bundle:

  • Stat size — the size of the chunk before Webpack has performed any magic on it.
  • Parsed size — the size of the processed chunk (post-uglification/minification/etc).
  • Gzipped size — the size of the processed chunk after it’s been gzipped.

At Flatiron, we use the gzipped figure for tracking changes in bundle size because it represents how much data is actually going to be sent over the wire when a user’s browser makes a request for a particular bundle.

Liftoff

To start the Bundle Analyzer plugin’s server, run the following command:

NODE_ENV=production bin/webpack

After Webpack is done compiling, you should see this output in your terminal:

Webpack Bundle Analyzer is started at http://127.0.0.1:8888
Use Ctrl+C to close it

And that’s it! We now have all of the tools that we’ll need on our bundle-trimming adventures. Join us in part 2 to dive into some of the issues we identified that Webpack and Webpacker’s defaults weren’t accounting for and how we fixed them.

Thanks for reading!

P.S.: Want to work on a mission-driven team that loves ice cream and optimized JavaScript build pipelines? We’re hiring!

Resources

  1. Webpacker
  2. Webpack Bundle Analyzer
  3. Other Webpack bundle visualization options

Footnotes

  1. Webpacker is nearing a stabilization release centered on Webpack 4, but at the time of writing it remains in beta. Consequently, we’re running Webpacker 3.5.3 and Webpack 3.12.1 in production.

To learn more about Flatiron School, visit the website, follow us on Facebook and Twitter, and visit us at upcoming events near you.

Flatiron School is a proud member of the WeWork family. Check out our sister technology blogs WeWork Technology and Making Meetup.