rel="prefetch"仅在页面onload完成、浏览器空闲、未卸载且满足同源、静态写入head、正确as属性时,低优先级预取资源存入HTTP缓存,对首屏无加速作用。

rel="prefetch" 不是“预加载”,也不是“强制提前下载”,它只在浏览器空闲时、带宽有余量、且资源被判定为“很可能后续用到”时才触发——多数情况下,它对首屏无影响,但滥用反而会挤占真实关键请求的带宽。
什么时候 rel="prefetch" 才真正生效
浏览器只在以下条件同时满足时才会发起 prefetch 请求:
- 当前页面已基本稳定(
document.readyState === 'interactive'或'complete') - 网络空闲(无正在进行的 high-priority fetch,如
script、img、font加载) - 用户尚未跳转,但浏览器根据导航历史或 link 标签位置推测下一步可能访问(例如:当前页末尾有指向下一页的
<a href="/next">,且该 link 同时带rel="prefetch") - 目标资源类型被支持(Chrome 支持
script、style、document、font;Firefox 支持类似,但对document更保守)
<link rel="prefetch"> 的写法和常见错误
必须放在 <head> 中,且 href 必须是绝对或根相对路径(不能是相对路径如 ./page.js,否则可能解析失败):
<link rel="prefetch" href="/js/next-page.bundle.js" as="script"> <link rel="prefetch" href="/css/landing.css" as="style"> <link rel="prefetch" href="/about.html" as="document">
容易踩的坑:
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
立即学习“前端免费学习笔记(深入)”;
- 漏写
as属性:不加as时,浏览器按fetch()默认模式处理(destination: 'empty'),无法复用缓存、不参与资源优先级调度,几乎等于白写 - 误用
rel="preload"替代:后者是 high-priority、阻塞渲染的,用于当前页关键资源;混用会导致带宽争抢,反而拖慢首屏 - prefetch 跨域资源未配 CORS:若目标资源需凭凭据(如 cookie),且跨域,必须确保响应头含
Access-Control-Allow-Origin,否则即使下载了也无法使用
如何验证 prefetch 是否被触发
打开 Chrome DevTools → Network 面板 → 勾选 “All” → 刷新页面 → 查找请求的 Initiator 列是否为 prefetch,且 Priority 显示为 Low 或 Idle:
- 如果没看到,先确认页面是否已进入空闲状态(可等 2–3 秒再刷新 Network)
- 如果看到但
Priority是High,说明你写了rel="preload"而非prefetch - 如果看到
Failed且提示net::ERR_ABORTED,大概率是资源被取消(因导航发生、内存压力或策略干预),属正常行为,不是 bug
哪些资源不该用 rel="prefetch"
它不适合:
- 体积过大(>500KB)的 JS/CSS:prefetch 不中断,但会延长整体资源队列,可能延迟后续真实导航的加载
- 带用户态参数的 URL(如
/api/user?uid=123):prefetch 是无上下文的静态请求,无法携带 cookie 或动态 header,且结果不可复用 - 第三方脚本(如广告、统计 SDK):它们常依赖执行时机与上下文,prefetch 下载后也不会自动执行,还可能触发无效埋点
- 同一资源多次 prefetch:浏览器会去重,但写多个相同
href的 link 标签仍会增加 DOM 解析开销
真正值得 prefetch 的,只有那些路径确定、体积适中、且用户行为链路高度可预测的资源——比如分页列表的下一页 HTML、登录后大概率跳转的仪表盘 JS、文档站点中相邻章节的 Markdown 渲染脚本。其余情况,不如交给 HTTP/2 Server Push 或现代打包工具的 code-splitting + dynamic import。


















