ビルドパフォーマンス

このガイドでは、ビルド/コンパイルのパフォーマンスを向上させるための便利なヒントを紹介します。


一般

以下のベストプラクティスは、開発または本番でビルドスクリプトを実行しているかどうかにかかわらず役立ちます。

最新の状態を維持する

最新のwebpackバージョンを使用してください。私たちは常にパフォーマンスの改善に取り組んでいます。推奨される最新のwebpackバージョンは

latest webpack version

Node.jsを最新の状態に保つことも、パフォーマンスに役立ちます。これに加えて、パッケージマネージャー(例:npmまたはyarn)を最新の状態に保つことも役立ちます。新しいバージョンは、より効率的なモジュールツリーを作成し、解決速度を向上させます。

ローダー

必要な最小限のモジュール数にローダーを適用します。代わりに

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
      },
    ],
  },
};

includeフィールドを使用して、実際に変換する必要があるローダーモジュールのみを適用します

const path = require('path');

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve(__dirname, 'src'),
        loader: 'babel-loader',
      },
    ],
  },
};

ブートストラップ

追加のローダー/プラグインごとに起動時間があります。できるだけ少ないツールを使用するようにしてください。

解決

次の手順で解決速度を向上させることができます

  • resolve.modulesresolve.extensionsresolve.mainFilesresolve.descriptionFilesのアイテムの数を最小限に抑えます。これらは、ファイルシステム呼び出しの数を増やすためです。
  • シンボリックリンク(例:npm linkまたはyarn link)を使用しない場合は、resolve.symlinks: falseを設定します。
  • コンテキスト固有ではないカスタム解決プラグインを使用する場合は、resolve.cacheWithContext: falseを設定します。

Dlls

変更頻度の低いコードを別のコンパイルに移動するには、DllPluginを使用します。これにより、アプリケーションのコンパイル速度が向上しますが、ビルドプロセスの複雑さが増します。

小さいほど速い

ビルドパフォーマンスを向上させるために、コンパイルの合計サイズを小さくしてください。チャンクを小さく保つようにしてください。

  • より少ない/より小さなライブラリを使用してください。
  • マルチページアプリケーションでSplitChunksPluginを使用します。
  • マルチページアプリケーションでasyncモードでSplitChunksPluginを使用します。
  • 未使用のコードを削除します。
  • 現在開発中のコードの部分のみをコンパイルします。

ワーカープール

thread-loaderを使用すると、負荷の高いローダーをワーカープールにオフロードできます。

永続キャッシュ

webpack設定でcacheオプションを使用します。package.json"postinstall"でキャッシュディレクトリをクリアします。

カスタムプラグイン/ローダー

ここでパフォーマンスの問題を引き起こさないようにプロファイルしてください。

プログレスプラグイン

webpack の設定から ProgressPlugin を削除することで、ビルド時間を短縮できる可能性があります。ただし、ProgressPlugin は高速なビルドではそれほど価値がない可能性があることにも留意してください。したがって、使用することの利点を十分に活用していることを確認してください。


開発

以下の手順は、特に開発において役立ちます。

インクリメンタルビルド

webpack の watch モードを使用してください。ファイルの監視や webpack の起動に他のツールを使用しないでください。組み込みの watch モードはタイムスタンプを追跡し、この情報をキャッシュの無効化のためにコンパイルに渡します。

一部のセットアップでは、監視がポーリングモードにフォールバックします。監視対象のファイルが多いと、CPU負荷が大きくなる可能性があります。このような場合は、watchOptions.poll を使用してポーリング間隔を増やすことができます。

メモリ内コンパイル

以下のユーティリティは、ディスクに書き込むのではなく、メモリ内でアセットをコンパイルおよび提供することでパフォーマンスを向上させます。

  • webpack-dev-server
  • webpack-hot-middleware
  • webpack-dev-middleware

stats.toJson の速度

Webpack 4 は、デフォルトで stats.toJson() で大量のデータを出力します。インクリメンタルなステップで必要でない限り、stats オブジェクトの一部分を取得することは避けてください。v3.1.3 以降の webpack-dev-server には、インクリメンタルビルドのステップごとに stats オブジェクトから取得するデータ量を最小限に抑えるための大幅なパフォーマンス修正が含まれていました。

Devtool

異なる devtool 設定間のパフォーマンスの違いに注意してください。

  • "eval" は最高のパフォーマンスを発揮しますが、トランスパイルされたコードには役立ちません。
  • cheap-source-map のバリアントは、マッピング品質がわずかに悪くても構わない場合に、よりパフォーマンスが高くなります。
  • インクリメンタルビルドには eval-source-map のバリアントを使用してください。

プロダクション固有のツールを避ける

特定のユーティリティ、プラグイン、ローダーは、プロダクション用にビルドする場合にのみ意味があります。たとえば、開発中に TerserPlugin を使用してコードを最小化および難読化することは通常意味がありません。これらのツールは通常、開発時には除外する必要があります。

  • TerserPlugin
  • [fullhash]/[chunkhash]/[contenthash]
  • AggressiveSplittingPlugin
  • AggressiveMergingPlugin
  • ModuleConcatenationPlugin

最小限のエントリーチャンク

webpack は、更新されたチャンクのみをファイルシステムに出力します。一部の設定オプション (HMR、output.chunkFilename[name]/[chunkhash]/[contenthash][fullhash]) では、変更されたチャンクに加えてエントリーチャンクが無効になります。

エントリーチャンクを小さく保つことで、出力コストを低く抑えてください。次の設定では、ランタイムコード用の追加チャンクが作成されるため、生成コストが安くなります。

module.exports = {
  // ...
  optimization: {
    runtimeChunk: true,
  },
};

余分な最適化ステップを避ける

webpack は、サイズとロードパフォーマンスのために出力を最適化するための追加のアルゴリズム処理を実行します。これらの最適化は、小規模なコードベースではパフォーマンスが優れていますが、大規模なコードベースではコストがかかる可能性があります。

module.exports = {
  // ...
  optimization: {
    removeAvailableModules: false,
    removeEmptyChunks: false,
    splitChunks: false,
  },
};

パス情報なしの出力

webpack には、出力バンドルにパス情報を生成する機能があります。ただし、これにより、数千のモジュールをバンドルするプロジェクトにガベージコレクションの負荷がかかります。options.output.pathinfo 設定でこれをオフにします。

module.exports = {
  // ...
  output: {
    pathinfo: false,
  },
};

Node.js バージョン 8.9.10-9.11.1

Node.js バージョン 8.9.10 - 9.11.1 の ES2015 Map および Set の実装には、パフォーマンスの低下がありました。webpack はこれらのデータ構造を頻繁に使用するため、このパフォーマンスの低下はコンパイル時間に影響します。

以前および以降の Node.js バージョンは影響を受けません。

TypeScript ローダー

ts-loader を使用する際のビルド時間を改善するには、transpileOnly ローダーオプションを使用します。このオプションは単独で型チェックをオフにします。型チェックを再度有効にするには、ForkTsCheckerWebpackPlugin を使用します。これにより、TypeScript の型チェックと ESLint のリンティングをそれぞれ別のプロセスに移動することで高速化されます。

module.exports = {
  // ...
  test: /\.tsx?$/,
  use: [
    {
      loader: 'ts-loader',
      options: {
        transpileOnly: true,
      },
    },
  ],
};

プロダクション

以下の手順は、特にプロダクションにおいて役立ちます。

ソースマップ

ソースマップは非常にコストがかかります。本当に必要ですか?


特定のツールに関する問題

次のツールには、ビルドパフォーマンスを低下させる可能性のある特定の問題があります。

Babel

  • プリセット/プラグインの数を最小限に抑えてください

TypeScript

  • 別のプロセスで型チェックを行うために fork-ts-checker-webpack-plugin を使用します。
  • 型チェックをスキップするようにローダーを設定します。
  • ts-loaderhappyPackMode: true / transpileOnly: true で使用します。

Sass

  • node-sass には、Node.js スレッドプールのスレッドをブロックするバグがあります。thread-loader と一緒に使用する場合は、workerParallelJobs: 2 を設定します。

6 貢献者

sokratbroadleybyzykmadhavarshneywizardofhogwartsanikethsaha