このガイドでは、ビルド/コンパイルのパフォーマンスを向上させるための便利なヒントを紹介します。
以下のベストプラクティスは、開発または本番でビルドスクリプトを実行しているかどうかにかかわらず役立ちます。
最新のwebpackバージョンを使用してください。私たちは常にパフォーマンスの改善に取り組んでいます。推奨される最新のwebpackバージョンは
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.modules
、resolve.extensions
、resolve.mainFiles
、resolve.descriptionFiles
のアイテムの数を最小限に抑えます。これらは、ファイルシステム呼び出しの数を増やすためです。npm link
またはyarn link
)を使用しない場合は、resolve.symlinks: false
を設定します。resolve.cacheWithContext: false
を設定します。変更頻度の低いコードを別のコンパイルに移動するには、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
Webpack 4 は、デフォルトで stats.toJson()
で大量のデータを出力します。インクリメンタルなステップで必要でない限り、stats
オブジェクトの一部分を取得することは避けてください。v3.1.3 以降の webpack-dev-server
には、インクリメンタルビルドのステップごとに stats
オブジェクトから取得するデータ量を最小限に抑えるための大幅なパフォーマンス修正が含まれていました。
異なる 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 の ES2015 Map
および Set
の実装には、パフォーマンスの低下がありました。webpack はこれらのデータ構造を頻繁に使用するため、このパフォーマンスの低下はコンパイル時間に影響します。
以前および以降の Node.js バージョンは影響を受けません。
ts-loader
を使用する際のビルド時間を改善するには、transpileOnly
ローダーオプションを使用します。このオプションは単独で型チェックをオフにします。型チェックを再度有効にするには、ForkTsCheckerWebpackPlugin
を使用します。これにより、TypeScript の型チェックと ESLint のリンティングをそれぞれ別のプロセスに移動することで高速化されます。
module.exports = {
// ...
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true,
},
},
],
};
以下の手順は、特にプロダクションにおいて役立ちます。
ソースマップは非常にコストがかかります。本当に必要ですか?
次のツールには、ビルドパフォーマンスを低下させる可能性のある特定の問題があります。
fork-ts-checker-webpack-plugin
を使用します。ts-loader
を happyPackMode: true
/ transpileOnly: true
で使用します。node-sass
には、Node.js スレッドプールのスレッドをブロックするバグがあります。thread-loader
と一緒に使用する場合は、workerParallelJobs: 2
を設定します。