按需加载模块是优化首屏加载速度最直接有效的手段,核心是“只传必需的代码”,通过动态 import() 实现运行时异步加载、路由级代码分割及第三方库轻量化替代。

按需加载模块是优化首屏加载速度最直接有效的手段之一,尤其在弱网环境下,减少初始下载量比压缩单个文件更能立竿见影地缩短白屏时间。核心不是“少写代码”,而是“只传必需的代码”。
用动态 import() 替代静态 import
静态 import 会在构建时全部打包进主 bundle,哪怕只用了一次工具函数;而 import() 是运行时触发的异步加载,Webpack 或 Vite 会自动把它拆成独立 chunk。
- ❌ 错误写法(全量打包):
import { debounce } from 'lodash'→ 整个 lodash 打包进首页 - ✅ 正确写法(按需触发):
const { debounce } = await import('lodash/debounce')→ 只加载 debounce 模块 - 注意:不能写在模块顶层,必须放在函数、事件回调或条件分支里,比如按钮点击、页面挂载后、滚动进入可视区时
路由级代码分割(SPA 场景首选)
用户打开首页时,根本不需要 about、user-profile 等页面的逻辑。按路由拆分,能让首屏 JS 体积下降 40%~70%。
- Vue Router 示例:
{ path: '/about', component: () => import('@/views/About.vue') } - React Router v6.4+ 示例:配合
Suspense+React.lazy,或使用 loader 函数返回 Promise - 生成的 chunk 名可加注释,方便调试:
import(/* webpackChunkName: "about-page" */ '@/views/About.vue')
第三方库轻量化 + 条件加载
moment、lodash、monaco-editor 这类库体积动辄几百 KB,在弱网下极易拖垮首屏。不靠“删代码”,靠“换思路”。
立即学习“Java免费学习笔记(深入)”;
- 用更小的替代方案:date-fns(
- 按需导入 ESM 版本:
import format from 'date-fns/format',而非整个包 - 重型组件延迟初始化:编辑器、图表、地图等,封装为异步组件,仅在用户点击“编辑”或切换到对应 tab 时才加载
配合预加载与资源提示提升感知速度
光“拆”不够,还得“导流”——告诉浏览器哪些资源接下来大概率要用,提前调度。
-
<link rel="preload" href="critical-utils.js" as="script">:对首屏强依赖的模块主动预加载 -
<link rel="prefetch" href="dashboard-chart.js" as="script">:对后续路由可能用到的模块低优先级预取(空闲时加载) - 结合 IntersectionObserver,在元素即将进入视口前 300px 就触发 import(),实现“视觉无感加载”


















