バンドルサイズの最適化 — JavaScript総ペイロードの削減
minification以外のJavaScriptバンドルサイズ削減戦略を解説。tree shaking、コード分割、動的インポート、依存関係の監査、バンドル分析ツールをカバーします。
詳細な説明
バンドルサイズの最適化
Minificationはバンドルサイズの課題の一部に過ぎません。真の最適化には、出荷するコードの量、事前に読み込む量、ブラウザがパースする必要がある量を削減する技術の組み合わせが必要です。
バンドルの分析
最適化の前に、バンドルの中身を知る必要があります:
- webpack-bundle-analyzer — バンドル内容のビジュアルツリーマップ
- source-map-explorer — source mapを分析してファイルレベルの貢献を表示
npx vite-bundle-visualizer— Viteプロジェクト用- Bundlephobia — インストール前にパッケージサイズを確認
よくある発見:1つの大きな依存関係(moment.js、lodash、チャートライブラリ)がバンドル全体の30-50%を占めていることがあります。
Tree Shaking
Tree shakingは未使用のexportを排除します。効果的に機能するには:
// 良い:名前付きインポートはtree shakingを可能にする
import { debounce } from 'lodash-es';
// 悪い:デフォルトインポートはライブラリ全体を取り込む
import _ from 'lodash';
依存関係がES modules(package.jsonの"module"フィールド)を公開していることを確認してください。CommonJSモジュールは効果的にtree shakeできません。
コード分割
バンドルをオンデマンドで読み込まれる小さなチャンクに分割します:
// ルートベースの分割(React)
const Dashboard = React.lazy(() => import('./Dashboard'));
// 機能ベースの分割
const ChartLibrary = () => import('chart.js');
これにより、初期JavaScriptペイロードが現在のページに必要なものだけに削減されます。
依存関係の最適化
重いライブラリを軽い代替に置き換える:
moment.js(300KB)をdayjs(2KB)またはdate-fns(tree shakeable)にlodash(72KB)をlodash-es(tree shakeable)またはネイティブメソッドにuuidをcrypto.randomUUID()(組み込み)に
依存関係を定期的に監査:
npx depcheck # 未使用の依存関係を検出 npx npm-check-updates # アップデートを確認CDNから読み込むライブラリには**
externals**を使用。
クリティカルでないコードの遅延読み込み
クリティカルでない機能の読み込みを延期:
- 分析スクリプト(
deferまたはインタラクション後に読み込み) - チャットウィジェット(スクロールまたはクリック時に読み込み)
- ファーストビュー以下のコンポーネント(intersection observer)
- ポリフィル(機能検出に基づく条件付き読み込み)
パフォーマンスバジェットの設定
サイズ制限を設定し、CIで強制します:
{
"budgets": [
{ "type": "initial-js", "maximumWarning": "150kb", "maximumError": "250kb" },
{ "type": "initial-css", "maximumWarning": "30kb", "maximumError": "50kb" }
]
}
webpack、Lighthouse、bundlesizeがこれらの制限を自動的に強制できます。
ユースケース
バンドルサイズの最適化は、グローバルなオーディエンス、モバイルユーザー、またはパフォーマンスに敏感な市場をターゲットとするWebアプリケーションにとって重要です。JavaScriptの1キロバイトがTime to Interactiveに直接影響し、低速3G接続のユーザーは200KBと500KBのバンドルの差を数秒の待ち時間として体験します。