ツリーシェイキングとは? バンドルから未使用コードを取り除く
ツリーシェイキングはモジュールグラフに対するデッドコード除去です。バンドラーは、アプリ内の何もが実際にはインポートしていない export を破棄します。
大きなライブラリから 1 つの関数だけをインポートするとき、ライブラリ全体をバンドルに入れたくはありません。ツリーシェイキングは、どの export が実際に使われているかを解析し、残りを取り除きます。木を揺らして枯れ葉を落とし、生きたコードだけを残すという比喩です。これはコードや依存関係がどう書かれているかに大きく依存します。
なぜ ES モジュールが必要なのか
ツリーシェイキングが機能するのは、ES モジュールの import と export が静的で、build 時に解析可能だからです。バンドラーは、どの export が参照されているかを正確に把握できます。古い CommonJS モジュールは動的なので、未使用コードを安全に除去できると証明するのははるかに困難です。
副作用が shaking を妨げる
あるモジュールがインポートされるだけで何らかの処理を行う場合 (たとえばグローバルを登録する場合)、その export が使われなくてもバンドラーはそれを残さなければなりません。package.json の sideEffects フィールドは、どのファイルを安全に破棄できるかをバンドラーに伝えます。
得られるもの
- より小さなバンドルとより速いページ読み込み。
- 帯域幅と CDN コストの削減。
- ブラウザが解析して実行する JavaScript の削減。
期待外れになるとき
ES モジュールとして書かれていないライブラリや、広範な副作用を持つライブラリは、うまく shaking できません。すべてを再 export する barrel file からインポートすると、予想以上のものを取り込むこともあります。確実に知る唯一の方法は、バンドルを計測することです。
CI/CD でのツリーシェイキング
ツリーシェイキングは本番バンドルのステップ中に自動的に実行されるため、別途ステージを要しません。CI が加えるのは検証です。pipeline での bundle-size チェックは、偶発的な import が出力を膨張させたときに build を失敗させ、リグレッションが出荷される前に検出できます。
重要なポイント
- ツリーシェイキングは、ES モジュールの静的解析に依拠して未使用の export を取り除きます。
- 副作用は除去を妨げます。sideEffects フィールドがバンドラーを導きます。
- CI の bundle-size チェックは、ツリーシェイキングが無効化されたときのリグレッションを検出します。