LoginSignup
180
137

More than 5 years have passed since last update.

webpackを可視化するツールを紹介

Posted at

フロントエンドのビルド(webpack)に関わる部分でパフォーマンス改善を考える時に、
現状を可視化するため、いくつかプラグインを使ってみましたので、軽く紹介したいと思います

可視化したい対象は以下の2つです
・webpackの速度改善の為、遅いloaderやpluginを知りたい
・バンドルファイルのサイズを減らしたいので、バンドルファイル内の各パッケージがどのくらいの容量を占めているか知りたい

今回分析に使ったコードはこちらです
https://github.com/kurosame/vuejs-boilerplate

遅いloaderやpluginを知りたい

speed-measure-webpack-plugin

$ yarn add --dev speed-measure-webpack-plugin
webpack.config.js
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin()

// webpackConfigをラップする
module.exports = smp.wrap({
  entry: {
  ...
})
$ npx webpack

■ 結果
 2018-04-17 18.54.38.png

全体で約6.5秒くらいかかってるのですが、そのうちのほとんどがTypeScript関連の処理に時間がかかっているのが分かります
(babel-loader and ts-loader and tslint-loaderの所)

実際のwebpack設定を見ると以下のようになってました

webpack.config.js
...
module.exports = {
  module: {
    rules: [
      ...
      {
        test: /\.ts$/,
        use: [
          {
            loader: 'babel-loader?cacheDirectory'
          },
          {
            loader: 'ts-loader',
            options: {
              appendTsSuffixTo: [/\.vue$/],
              transpileOnly: true
            }
          },
          {
            loader: 'tslint-loader',
            options: {
              typeCheck: true
            }
          }
        ],
        exclude: /node_modules/
      }
      ...
    ]
  }
}

ここをターゲットに調べるとtslint-loaderのtypeCheckに3.5秒かかっていることが分かりました
少し調べるとtslint-loaderのtypeCheckが遅いことがissuesに上がってました
https://github.com/wbuchwalter/tslint-loader/issues/76

バンドルファイル内の各パッケージがどのくらいの容量を占めているか知りたい

webpack-bundle-analyzer

$ yarn add --dev webpack-bundle-analyzer
webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = {
  ...
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}
$ npx webpack

ブラウザがhttp://127.0.0.1:8888/で立ち上がり、以下のような結果が表示されます

 2018-04-17 17.52.47.png

今回分析に使ったコードでは、webpack実行時に2つのファイルを出力するようにしています
実装したコードをバンドルしたbuild-[ハッシュ値].jsとサードパーティー系のパッケージのみをバンドルしたvendor-[ハッシュ値].jsになります
vendorの方がサイズが大きくなると予想してましたが、結果はほぼ同じくらいのサイズでした

結果を見てみると、babel-runtimeとnormalize.cssらへんが大きいことが分かります

babel-runtimeは新しい書き方(EcmaScript)で実装したコードをレガシーブラウザでも動くように変換するライブラリなので、
IEなどをターゲットにしているプロジェクトだと使わないわけにはいきません

normalize.cssはクロスブラウザでデフォルトのスタイルの差異を無くすため、初期デフォルトスタイルを提供してくれるライブラリです
今まで意識してなかったので、ここまで重いとは思いませんでした。。
調べてみると、今回分析に使ったコードではnormalize.cssはv7.0.0を使っています。
現在の最新はv8.0.0でこのバージョンでは古いバージョンのブラウザを対象外としている為、大幅な軽量化がされたみたいです
単純にバージョンを上げるだけでもバンドルサイズの削減ができそうです

また、IEをサポートする必要がない場合は、modern-normalizeというライブラリを検討するのも良さそうというもの分かりました
https://github.com/sindresorhus/modern-normalize

またnormalize.cssを使わずに自作する選択肢もありかもしれません

webpack-bundle-size-analyzer

webpack-bundle-analyzerだとvendorが上手く可視化できなかったので、webpack-bundle-size-analyzerを使って可視化しました

$ npx webpack --config webpack.vendor.config.js --profile --json > stats.json
$ npx webpack-bundle-size-analyzer stats.json

 2018-04-18 14.14.41.png

source-map-explorer

こちらもwebpack-bundle-analyzerと同様にバンドルファイルの中身を可視化できます

webpack.config.js
module.exports = {
  output: {
    filename: '[name]-[hash].js',
    path: path.resolve(__dirname, 'dist'),
    sourceMapFilename: '[file].map',
  },
  devtool: '#source-map' // inline-source-mapだと駄目だった
}
$ npx source-map-explorer dist/bundle-[ハッシュ値].js

 2018-04-18 11.47.26.png

こちらは全体のサイズやパーセントが見れるし、グリッドデザインで見やすいです

webpack-visualizer-plugin

こちらもwebpack-bundle-analyzerと同様にバンドルファイルの中身を可視化できます

$ yarn add --dev webpack-visualizer-plugin
webpack.config.js
const Visualizer = require('webpack-visualizer-plugin')

module.exports = {
  ...
  plugins: [
    new Visualizer()
  ]
}

先程のプラグインと比べて、だいぶ見せ方が違いますね

 2018-04-18 14.28.17.png

カーソルを合わすと、以下のようにサイズとパーセントが表示されます

 2018-04-18 14.29.10.png

180
137
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
180
137