Webpack でパフォーマンス バジェットを設定する

Webpack は、インポートされたすべてのファイルを結合し、バンドルと呼ばれる 1 つ以上の出力ファイルにパッケージ化します。バンドルは便利ですが、アプリのサイズが大きくなるにつれてバンドルも大きくなります。バンドルのサイズをモニタリングして、サイズが大きくなりすぎないようにし、アプリの読み込み時間に影響しないようにする必要があります。Webpack は、アセットサイズに基づくパフォーマンス バジェットの設定をサポートしており、バンドルサイズを監視できます。

以下は、新年までの残り日数をカウントするアプリの例です。これは Reactmoment.js で構築されています。(フレームワークとライブラリに依存する実世界のアプリと同様に、😉?)

元日までの残り日数をカウントするアプリ

測定

このコードラボには、webpack にバンドルされたアプリがすでに含まれています。

  1. [Remix to Edit] をクリックして、プロジェクトを編集可能にします。
  2. [ターミナル] をクリックします(注: ターミナル ボタンが表示されない場合は、全画面表示オプションを使用する必要がある場合があります)。
  3. アセットとそのサイズのリスト(色分け)を取得するには、コンソールに webpack と入力します。
webpack

メイン バンドルは 244 KiB(250 KB)を超えているため、黄色でハイライト表示されています。

バンドルサイズが 323 KiB であることを示す Webpack の出力
Webpack がかさばる JS バンドルについて警告 ⚠️

これらの警告は、本番環境モードでデフォルトで有効になっています。アセットとエントリ ポイント(ページの初回読み込み時に使用されるすべてのアセットの組み合わせ)の両方で、デフォルトのしきい値は圧縮されていない 244 KiB です。

アセットが推奨サイズの上限を超えていることを示す Webpack の警告
Webpack がかさばる JS バンドルに警告 ⚠️

Webpack は警告だけでなく、バンドルを縮小する方法に関する推奨事項も提供します。推奨される手法について詳しくは、Web Fundamentals をご覧ください。

Webpack のパフォーマンスの最適化に関する推奨事項
Webpack パフォーマンスの最適化に関する推奨事項 💁?

カスタムのパフォーマンス予算を設定する

適切なパフォーマンス予算は、プロジェクトの性質によって異なります。ご自身で調査することをおすすめします。圧縮または圧縮して縮小したクリティカル パス リソースを 170 KB 未満で配信することをおすすめします

このシンプルなデモでは、さらに保守的に予算を 100 KB(97.7 KiB)に設定します。webpack.config.js に以下を追加します。

module.exports = {
  //...
  performance: {
    maxAssetSize: 100000,
    maxEntrypointSize: 100000,
    hints: "warning"
  }
};

新しいパフォーマンス予算はバイト単位で設定します。

  • 個々のアセットに 100,000 バイト(maxAssetSize)
  • エントリ ポイントの 100,000 バイト(maxEntrypointSize)

この場合、バンドルは 1 つだけであり、エントリ ポイントとしても機能します。

hints に指定できる値は次のとおりです。

  1. warning(デフォルト): 黄色の警告メッセージが表示されますが、ビルドは合格します。開発環境で使用することをおすすめします。
  2. error: 赤色のエラー メッセージが表示されますが、ビルドは合格します。この設定は、本番環境ビルドに推奨されます。
  3. false: 警告やエラーは表示されません。
赤いフォントの Webpack パフォーマンス エラー
Webpack パフォーマンス ヒント「error」🚨?

最適化

パフォーマンス バジェットの目的は、パフォーマンスの問題が解決できなくなる前に警告することです。アプリを構築する方法は常に複数あり、一部の手法では読み込み時間が短縮されます。(その多くは、JavaScript の最適化に記載されています。🤓?)

フレームワークとライブラリはデベロッパーの作業を楽にしますが、エンドユーザーはアプリの作成方法ではなく、機能と速度のみを重視します。パフォーマンス予算を超えている場合は、最適化の可能性を検討してください。

実際のところ、大規模なクライアントサイド フレームワークは通常、入れ替えが難しいため、賢く使用することが重要です。少し調べれば、人気のあるライブラリに代わる、同じくらい優れた小規模なライブラリを見つけることができます(date-fnsmoment.js の優れた代替手段です)。フレームワークやライブラリがパフォーマンスに大きな影響を与える場合は、フレームワークやライブラリをまったく使用しないほうがよいこともあります。

不要なコードを削除することは、大規模なサードパーティ製ライブラリを含むアプリを最適化する良い方法です。使用していないコードを削除するガイドでは、このプロセスについて詳しく説明しています。ここでは、moment.js を使用せずにカウントダウン コードを簡単に書き換える方法をご紹介します。

app/components/Countdown.jsx で、以下を削除します。

const today = moment();
const yearEnd = moment().endOf('year');
const daysLeft = yearEnd.diff(today, 'days');

この行を削除します。

const moment = require('moment');

少し計算が必要ですが、同じカウントダウンを JavaScript で実装することもできます。

const today = new Date();
const year = today.getFullYear();
const yearEnd = new Date(year,11,31); //months are zero indexed in JS
const timeDiff = Math.abs(yearEnd.getTime() - today.getTime());
const daysLeft = Math.ceil(timeDiff / (1000 * 3600 * 24));

次に、package.json から moment.js を削除し、コンソールで webpack を再度実行して、最適化されたバンドルをビルドします。

じゃーん!223 KiB(230 KB)削減し、アプリのサイズが予算内に収まりました。🎉?

最適化後の Webpack バンドルのサイズ出力は 97.7 KiB

モニタリング

webpack でパフォーマンス バジェットを設定するには、数行のコードのみで済みます。また、大きな依存関係を(誤って)追加した場合は警告が表示されます。「見えないものは意識にない」という格言がありますが、webpack を使用すると、パフォーマンスへの影響を常に把握できます。