出発点
- 初期バンドル: 412kb (gzip)
- LCP: 3.8s (mobile 4G)
- ユーザ離脱: トップで 32%
やったこと(効いた順)
1. 重い依存の置換 (-87kb)
moment.js→date-fnslodash→ 個別 import (lodash-es/debounce等)chart.js→dynamic importで遅延化
2. ルート分割 (-58kb)
管理画面のコードが公開ページのバンドルに混入していた。next/dynamic で分離。
const Editor = dynamic(() => import('./Editor'), { ssr: false });
3. 不要な polyfill (-32kb)
browserslist を絞った。IE 系のレガシーは別ビルドに分離。
4. アイコンのツリーシェイク (-28kb)
react-icons を全部入れていた → lucide-react の個別 import に変更。
5. 画像と CSS の見直し (-4kb)
誤差レベルだが、ついで。
結果
| 指標 | Before | After | Δ |
|---|---|---|---|
| Bundle (gzip) | 412kb | 203kb | -50.7% |
| LCP (4G) | 3.8s | 1.9s | -50% |
| 直帰率 | 32% | 24% | -8pt |
学び
計測しないと、何を消していいのか分からない。
next build --analyzeを 30 分眺めるだけで、半分以上の改善余地は見つかる。
#Performance#Webpack#Vite#Bundle