预加载模块是提前在后台拉取资源以实现零延迟使用,关键在于选对时机、控制优先级并做好降级兜底;推荐用 requestIdleCallback 在空闲时触发 import(),配合超时设置与错误处理,也可基于用户行为(如 hover、focus)或路由切换前预加载,构建工具如 Vite 会自动注入 modulepreload。

预加载模块不是等用户点一下才开始请求,而是提前在后台悄悄拉取资源,等真正要用时直接从缓存里拿,几乎零延迟。关键在于“提前”和“不阻塞”,得选对时机、控制好优先级、并做好降级兜底。
用 import() 配合空闲时机预加载
在页面空闲、用户没在操作时发起预加载,既不影响体验,又为后续动作铺路。推荐用 requestIdleCallback,它会在浏览器空闲时段执行回调:
- 写法示例:
requestIdleCallback(() => import('./analytics.js')); - 注意:需加 try/catch 或 .catch() 处理网络失败,避免静默报错
- 可设超时兜底:
requestIdleCallback(() => import('./analytics.js'), { timeout: 2000 });,确保两秒内至少触发一次
根据用户行为信号提前触发
鼠标悬停、焦点进入、滚动接近某区域——这些都可能是使用意图的信号。比如导航菜单展开前,预加载子页面模块:
menuButton.addEventListener('mouseenter', () => import('./admin-dashboard.js'));- 适合体积中等、命中率高的模块;太重的模块(如编辑器)建议改用点击后加载+骨架屏
- 避免重复触发:可用布尔标记或 Promise 缓存,例如
const preload = preload || import(...)
路由切换前预加载目标模块
在用户还没点进新页面时,就预取下一路由对应的代码块。现代框架底层已封装,但手动实现也很清晰:
立即学习“Java免费学习笔记(深入)”;
- 监听路由变化事件(如 History API 的
popstate),或在导航链接onmouseover时调用import() - React Router v6.4+ 可结合
createBrowserRouter和loader函数,在跳转前 resolve 模块 - Vue Router 中常用
beforeEach全局守卫 +import()实现“跳转即加载”
构建工具层面配合预加载提示
纯 JS 预加载是运行时策略,而构建工具(Vite/Webpack)能在打包阶段注入 <link rel="modulepreload"> 标签,让浏览器更早发起请求:
- Vite 默认对
import()表达式自动添加modulepreload,无需额外配置 - Webpack 需启用
optimization.moduleIds: 'deterministic'并配合SplitChunksPlugin才能稳定生成预加载提示 - 注意:预加载只管下载和解析,不执行;真正
await import()时才执行模块初始化逻辑


















