Webpack: here are a few tricks that can boost your build performance

  • Post by Nicolas Ramz
  • Nov 07, 2016
Webpack: here are a few tricks that can boost your build performance

Webpack is a nice tool but the default configuration can be very slow at generating builds, even for small projects. Fortunately it takes only a few modifications to drastically reduce build times.

I started switching to webpack for a new ES6 / Html 5 project I’m working on: it’s a game engine that has about thirty files and only a few dependencies.

While webpack quickly gives a few advantages (incremental builds, etc), I quickly noticed that the build process was rather slow.

Here are the build times using the default options:

NUM FILES       INITIAL BUILD TIME         INCREMENTAL BUILD TIME
141             11800ms                   2400ms

Note: there are 141 files in total but most files come from the few dependencies I’m using: fetch & promise, etc… my project really contains about 30 files.

This is on a Core i5-4590 CPU running at 3.30Ghz: not a state of the art CPU but not an old dog either.

Here is the webpack.config.js file (only interesting parts):

module.exports = {
  /* ... */
  entry: [
    'es6-promise',
    'whatwg-fetch',
    './gods/js/gods.js'
  ],
  devtool: inline-source-map,
  module: {
    loaders: [
      { test: /\.js$/, loader: 'babel-loader', exclude: 'node_modules' }
    ]
  },
  resolve: {
    modulesDirectories: [ 'js', 'gods/js', 'node_modules'],
    root: [ path.resolve('./js/', path.resolve('./js/lib') ]
  }
  /* ... */
}

Searching Google for “webpack performance build” quickly points to this page on the webpack’s website.

First advice is to avoid using modulesDirectories. Ok, so let’s make the following changes:

module.exports = {
  /* ... */
  resolve: {
    modulesDirectories: [ 'node_modules'],
    root: [ path.resolve('./js/', path.resolve('gods/js'), path.resolve('./js/lib') ]
  }
  /* ... */
}

Here are the results:

NUM FILES       INITIAL BUILD TIME         INCREMENTAL BUILD TIME
141             9912ms                   1984ms

That’s better: initial builds are now 16% quicker but incremental build didn’t improve that much.

Let’s see what else we can do. The same webpack page states that the sourcemap generation may also slow down builds a lot.

Changing the devtool from ‘inline-source-map’ to ‘eval-cheap-module-source-map’ produces the following results:

NUM FILES       INITIAL BUILD TIME         INCREMENTAL BUILD TIME
141             9021ms                   703ms

That’s a 23% decrease on initial build time and a huge 71% speed up on incremental builds: now this is getting interesting!

The documentation also suggests to add this:

module.exports = {
  /* ... */
  output: {
    pathinfo: true
  }
  /* ... */
}

But this doesn’t make a difference in build time, it only gives better source mapping.

Ok, let’s dig the internet for some more performance improvements. Reading the comments on webpack’s GitHub it seems there are some plugins that may speed up build process even more.

DllPlugin is one of them but seems to be difficult to configure. But it seems another one: Happypack can give similar performance gains without having trouble configuring it.

It is still in beta but seems to be already in use by a lot of people, so let’s give it a look.

The changes are indeed very small to make it work: after having installed it using the usual

npm install --save-dev happypack 

Happypack only needs to be added to the list of Webpack plugins:

var HappyPack = require('happypack');

module.exports = {
  /* ... */
  plugins: [
    new HappyPack({
      loaders: [ 'babel?presets[]=es2015' ]
    }),
    /*... */
  ]
  /* ... */
}

Now the only remaining step is to replace the babel loader so that it uses Happypack:

module.exports = { /* … / module: { plugins: [ { test: /.js$/, loader: ‘happypack/loader’, exclude: /node_modules/ } // ] / … */ } }

That’s it!

And the results are impressive!

NUM FILES       INITIAL BUILD TIME         INCREMENTAL BUILD TIME
141             2533ms                   429ms

That’s a massive 79% speed up in initial build time and 82% speed up in incremental build!

Of course, this may depend on your project and number of files, but very little changes can make a big impact on build time.

Now I can get back to happy coding: JavaScript development was starting to become like Java: I was starting to spend more time for the build to finish that coding ;)

Update: all performance tests were performed using webpack version 1.14.0 and should be valid for version 1.x of webpack.