sourcemap を無効化して webpacker の production build を 2000% 速くする

  • 51
    Like
  • 3
    Comment

TL;DR

プロダクションで sourcemap が有効化されていたので、関連オプションを切って回ったら 2000% 高速化した。

問題

NODE_ENV=production bundle exec rake webpacker:compile が致命的に遅かった。

エントリーポイントが17個でビルド時間が合計680s という有様で、プロダクションとはいえ デプロイ を11分遅くさせるのは、ビジネス的に致命的な感じだった。

調査

さしあたり、いつもの経験則で uglify の mangle オプションが遅いんだろう、と思って、webpacker のソースの設定を見に行ったら、うん????となる設定をみつけた。

https://github.com/rails/webpacker/blob/master/package/environments/production.js#L11-L19

    this.plugins.set('UglifyJs', new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      },
      output: {
        comments: false
      }
    }))

いやー、プロダクションにはsourcemapいらないだろと思って、 webpacker の既定値を無理矢理書き換えた。

config/webpack/environment.js
const webpack = require('webpack');
const environment = require('./environment').toWebpackConfig();

// UglifyJsPlugin のインスタンスを見つけて置き換える
environment.plugins = environment.plugins
  .map(plug => {
    if (plug instanceof webpack.optimize.UglifyJsPlugin) {
      return new webpack.optimize.UglifyJsPlugin({
        sourceMap: false,
        parallel: true,
        mangle: false,
        uglifyOptions: {
          mangle: false
        },
        compress: {
          warnings: false
        },
        output: {
          comments: false
        }
      });
    }
    return plug;
  })

module.exports = environment;

ついでに並列オプションを有効化するなどして、 680s => 240s で 283% 速くなった。

config.devtool

ってことは webpack 側の devtool の sourcemap が有効になってるのでは? と思って、eval に戻してみた。

//...
environment.devtool = 'eval';
module.exports = environment;

240s => 34s

まとめ

元と比べて 2000%高速化しました。めでたしめでたし。

webpacker、設定がなんか富豪的な感じなんで、気をつけたい。