代码分割与懒加载的最佳实践

从路由级、组件级到库级,系统讲解代码分割的粒度选择与懒加载的正确姿势,附避坑指南。

代码分割是降低首屏体积最直接的手段。但「怎么分、分多细」有讲究,分错了反而更慢。

分割的三个粒度

路由级分割

最基础也最高效:每个路由一个 chunk,用户只加载访问到的页面。

const About = lazy(() => import('./About'));

配合 Suspense 显示加载态。

组件级分割

对首屏不需要的重组件(图表、编辑器、地图)做懒加载:

const Chart = lazy(() => import('./Chart'));

适用于「折叠在下方」「点击才展开」的内容。

库级分割

把体积大、使用频率低的库拆成独立 chunk,或按需引入其子模块。

懒加载的正确姿势

  • 配合 Suspense 提供优雅的 fallback;
  • 预加载:用户可能访问的模块,在空闲时预取:
import(/* webpackPrefetch: true */ './Detail');
  • 避免过度分割:chunk 太碎会导致大量小请求,HTTP/2 下虽可并行,但仍有开销。

常见坑

  • 懒加载首屏内容:首屏关键组件不该懒加载,否则拖慢 LCP;
  • 无加载态:网络慢时白屏,务必给 fallback;
  • 命名 chunk:用注释命名,便于分析产物。

分割的指导原则

以「用户交互路径」为边界:用户走到哪里,才加载哪里的代码。首屏只保留「立即需要」的部分。

结语

代码分割的目标不是「chunk 越多越好」,而是「让用户只为看到的内容付费」。以交互路径为边界,配合预加载,才能兼顾速度与体验。