prefetch 不会静默加载大资源,它仅在页面 onload 后、主线程空闲且带宽有余时低优先级尝试拉取并缓存,大资源极易被跳过或中断。

prefetch 会静默加载大资源吗
不会真正“静默预读取”,更不会保证加载完成。rel="prefetch"只是向浏览器发出一个低优先级提示:等当前页 onload 完、主线程空闲、带宽有余量时,才可能去拉取目标资源并存入 HTTP 缓存。它不阻塞渲染,也不抢占带宽——但正因如此,大资源(如 >500KB 的 JS chunk 或整页 HTML)极大概率被跳过、中断或延迟到用户已离开页面后才开始下载。
为什么大资源 prefetch 常失效或反效果
浏览器对 prefetch 的调度极其保守,大资源天然触发多个失败条件:
- 页面 onload 被长任务卡住(比如表单校验、第三方 SDK 初始化),prefetch 根本不启动
- 网络带宽余量不足时,浏览器直接丢弃该请求,连
net::ERR_FAILED都不报 - 目标资源体积过大,Chrome 可能主动截断(尤其移动端),Safari 则直接忽略
as="document" - 若服务端响应头缺失
Cache-Control: public, max-age=31536000,缓存立即失效,下次导航仍要重下
怎么写才能让大资源真正进缓存
关键不是“加大资源”,而是拆解、固定、精准声明:
-
href必须指向构建产物中路径稳定的静态文件,例如/assets/ReportPage.8a2b.js,绝不能是/report?tab=pdf或./report.js -
as必须准确:JS 用as="script",CSS 用as="style",图片用as="image";as="fetch"或as="json"无效 - 大 JS chunk 若含内联样式或字体,需额外加一行
<link rel="prefetch" href="/assets/ReportPage.e2d9.css" as="style"> - 必须静态写在 HTML 的
中,且位于<meta charset>和<title></title>之后、首个<link rel="stylesheet">之前
比 prefetch 更靠谱的大资源预取方式
当资源体积大、路径动态或用户行为明确时,硬编码 <link rel="prefetch"> 几乎不可控:
- 鼠标悬停卡片后 200ms 调用
import('./ReportPage'):浏览器自动预取对应 chunk,优先级略高于 prefetch,且全平台兼容 - 表单第一步提交成功后,立刻执行
const module = await import('./ReportPage'):资源在后台拉取,用户点“查看报告”时组件已就绪 - 对超大资源(如 PDF、视频封面图),改用
fetch(url, { method: 'HEAD' })探测可用性 + service worker 缓存,而非依赖 prefetch 的不可靠调度
复杂点在于:prefetch 不提供任何回调、不暴露加载状态、不支持取消。你只能控制它“往哪放”,无法知道它“放没放进去”。真要稳,就得绕开它,用 JS 主动触发。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











