prefetch请求未发出,需先检查三件事:link必须静态写在head中、目标URL必须同源、页面必须完成onload且浏览器处于空闲状态;Chrome默认过滤该请求,需手动勾选“prefetch”才能查看,资源强缓存时也不发起新请求。

prefetch 请求根本没发出去,先查这三件事
写了 <link rel="prefetch" href="/js/detail.js" as="script"> 却在 Network 面板里看不到请求,不是代码写错了,而是浏览器压根没触发它。必须同时满足三个硬性条件:
-
<link>必须静态写在 HTML 的<head>里,动态插入(比如document.head.appendChild())基本无效 - 目标 URL 必须同源——协议、域名、端口全一致;跨域时浏览器连 DNS 查询都不发起,Network 里静默消失
- 页面得真正触发
window.onload,且之后 CPU 和网络都空闲(没高优请求、没长任务卡主线程、用户没切页)
Chrome 默认过滤 prefetch 请求,得手动在 Network 面板顶部勾选 “prefetch” 才能看见;如果资源已强缓存(Cache-Control: immutable),它甚至不发请求,直接读磁盘缓存。
prefetch 的 as 属性填错,等于白写
as 不是可选装饰,它直接决定浏览器是否识别、怎么解析、进哪个缓存池。填错或漏填,结果可能是降级为 as="document",甚至整个标签被忽略:
- 预取下一页 HTML:必须用
as="document",不能写as="html"或留空 - 预取 JS 模块:用
as="script",不是as="module"(后者非法) - 预取 CSS:用
as="style",不是as="css" - 字体别乱用
as="font"—— prefetch 不触发 CORS 预检,跨域字体静默失败
验证很简单:Network → 筛选你的 prefetch 资源 → 看 Initiator 列是不是 prefetch,Priority 是不是 Low。如果不是,基本就是 as 错或路径 404。
立即学习“前端免费学习笔记(深入)”;
和 preload 混用时,带宽抢不过就拖慢首屏
preload 是 High/Highest 优先级,prefetch 是 Low,但它们共用同一套 HTTP/2 流和 TCP 连接。如果在 <head> 里同时写:
<link rel="preload" as="script" href="/critical.js"> <link rel="prefetch" as="script" href="/next-page.js">
浏览器会按优先级调度,但关键点在于:preload 可能打断正在加载的首屏图片或 CSS,而 prefetch 得等它跑完才启动。问题出在误判“关键”:
- 把本该用
preload的首屏 JS 写成prefetch→ 首屏交互延迟 - 把本该用
prefetch的下一页 JS 写成preload→ 白占 High 带宽,当前页 LCP 推后 - 对已用
type="module"或defer的脚本再加preload→ 冗余请求 + 带宽挤占
真实场景中,电商列表页预取商品详情页 JS,必须用 prefetch;而详情页自身核心 JS,才轮到 preload。
prefetch 缓存不等于可用,版本更新时容易失效
prefetch 把资源放进 HTTP 缓存,但不会自动执行、解析或挂载。它只解决“下载快”,不解决“用得对”:
- 资源没配
Cache-Control(比如max-age=3600),下次跳转时仍要重下,预取白做 - JS 文件没加哈希(如
detail.a1b2c3.js),上线新版本后旧缓存还在,用户拿到的是过期代码 - prefetch 的缓存和 preload 隔离——A 页面
preload过的字体,B 页面prefetch同一地址,仍要重新拉一次
最容易被忽略的是:prefetch 不提供任何 JS 接口,你没法监听它完成,也没法强制清掉它的缓存。它只是把文件丢进磁盘,等真实请求来时命中而已。



















