结论:rel="preload" 对动态路由脚本无效,它仅适用于当前页已知且立即需要的资源;动态路由应使用 rel="prefetch",在浏览器空闲时低优先级预取,路径需与 import() 请求完全一致才能命中缓存。

preload 不能用于动态路由脚本的预取
直接说结论:rel="preload" 对动态路由(如 React Router、Vue Router 的 lazy-loaded 模块)无效,写了也白写。它只对当前页面“已知路径、立即需要”的资源起作用,而动态 import() 的模块路径在构建时不确定、运行时才解析,浏览器根本无法在 HTML 解析阶段识别并提前发起请求。
常见错误现象:import('./routes/Profile.js') 对应的 chunk 文件,在 里硬写 <link rel="preload" href="Profile.abc123.js" as="script"> —— 路径可能随构建哈希变化,且该 JS 实际不会被当前页执行,浏览器会标记为 “unused preload”,DevTools Network 面板中 Priority 显示为 Low 或直接 canceled。
- 动态路由脚本本质是按需加载,不属于“当前页马上要用”的资源,
rel="preload"的语义和机制完全不匹配 - Webpack/Vite 打包生成的 chunk 名带哈希,静态写死
href必然失效,无法维护 - 即使路径侥幸正确,浏览器也不会将 preload 缓存用于后续
import()调用——script 缓存复用要求as="script"+ 完全一致的 URL + 同源/CORS 策略,而动态 import 的 fetch 请求走的是as="fetch"流程
动态路由脚本该用 prefetch,不是 preload
rel="prefetch" 才是解决动态路由预取的正确方案。它明确告诉浏览器:“这个资源用户**可能**在下一次导航中用到,请在空闲时低优先级下载”,正好匹配懒加载路由的使用场景。
实操建议:
- 在入口 HTML 的
中静态声明关键路由 chunk,例如:<link rel="prefetch" href="/assets/Profile.abc123.js" as="script"> - 路径必须是构建后确定的绝对或根相对地址;推荐配合 Webpack 的
webpackPrefetch: true或 Vite 的import.meta.webpackPrefetch自动生成,避免手写 - 不要给 prefetch 加
as="font"或crossorigin——字体 prefetch 易静默失败,且 prefetch 不触发 CORS 预检,加了反而可能干扰 - 如果路由模块依赖其他 chunk(比如 shared-utils.js),prefetch 只需声明入口模块,Webpack 会自动处理依赖图
prefetch 的生效验证比想象中难
写了 rel="prefetch" 不代表它真在空闲时拉取了。很多团队只检查代码存在就认为成功,结果上线后毫无效果。
验证要点:
- 打开 Chrome DevTools → Network 面板 → 过滤
prefetch→ 查看 Initiator 列是否为prefetch(不是parser或script) - 确认 Priority 列显示为
Low;若出现Highest,说明误用了preload - 跳转到对应路由后,目标 JS 应状态码为
200 (from memory cache)或304;若仍是200且 Size 显示网络传输量,说明未命中缓存 - 注意:prefetch 请求通常在主页面 load 事件之后才发出,别在页面刚加载完就刷新 Network 面板等着看
更稳的替代方案:用 preconnect + prefetch 组合
如果动态路由脚本托管在 CDN 或独立域名(如 https://js.example.com/),单靠 prefetch 效果有限——DNS 查询、TCP 握手、TLS 协商仍要耗时 300ms+。
正确做法是组合使用:
- 先声明
<link rel="preconnect" href="https://js.example.com" crossorigin>,务必加crossorigin,否则 Safari 和旧版 Chrome 忽略 - 再跟上
<link rel="prefetch" href="https://js.example.com/assets/Profile.abc123.js" as="script"> - preconnect 建议控制在 4–6 个以内,且不要紧挨着发请求,中间至少间隔 100ms,确保连接真正就绪
这种组合在真实弱网环境下提升明显,但容易被忽略的一点是:prefetch 的 href 必须与最终 import() 请求的 URL 完全一致(协议、域名、路径、查询参数),否则缓存不复用,等于白做。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











