JavaScript はウェブで最もコストの高いリソースです — バイト単位で見ると、JavaScript ファイルは 同等のサイズの画像よりコストが高く、デコードするだけでなくパースと実行が必要なためです。 500 KB の JavaScript バンドルは、中級スマートフォンでメインスレッドを 2〜4 秒間ブロックする 可能性があります。100 KB 未満にする方法を解説します。
ステップ 1: 現状を測定する
最適化の前に現在のバンドルを監査します。npx @next/bundle-analyzer を実行します。next.config.js で ANALYZE=true npm run build で有効にします。 ツリーマップはどのパッケージが最も大きく、どのページがどのモジュールを含むかを示します。
ステップ 2: 未使用の依存関係を削除する
| パッケージ | サイズ | 代替 | 代替サイズ |
|---|---|---|---|
| moment.js | 67 KB | date-fns(ツリーシェイク済み) | 3–8 KB |
| lodash | 72 KB | lodash-es(ツリーシェイク済み) | 1–5 KB |
| axios | 14 KB | fetch(ネイティブ) | 0 KB |
| react-icons(全体) | 340 KB | 個別 SVG インポート | 0.5 KB/アイコン |
ステップ 3: ツリーシェイキング
- バレルファイルからのデフォルトインポートではなく、名前付きインポートを使用する。
- ユーティリティモジュールでのサイドエフェクトインポートを避ける。
- ライブラリの package.json で
sideEffects: falseを確認する。
ステップ 4: コード分割
Next.js はページレベルで自動的にコードを分割します。サブページ分割には動的インポートを 使用します。リッチテキストエディター・チャートライブラリ・PDF ビューアー・マップコンポーネント・ タブやモーダルの後ろにある初期ロード時に非表示のコンポーネントが良い候補です。
ステップ 5: サードパーティスクリプトの最適化
Next.js の <Script> コンポーネントをサードパーティスクリプトに使用します:strategy="lazyOnload"(他のすべての後)、strategy="afterInteractive"(ハイドレーション後、ほとんどのアナリティクスに適切)、strategy="worker"(Web Worker 内、メインスレッドから完全に分離)。
Before / After: 実際の数値
| 指標 | Before | After |
|---|---|---|
| ホームページ JS(gzip) | 520 KB | 82 KB |
| メインスレッドブロック時間 | 3.2 秒 | 0.4 秒 |
| INP(75 パーセンタイル) | 480 ms | 95 ms |
| Lighthouse パフォーマンス | 61 | 94 |