link rel="prefetch" 不能“取数据”,它仅在浏览器空闲时下载资源存入HTTP缓存,不执行脚本、不触发API、不提供JS可读接口;需同源、置于head、页面未卸载且空闲时才生效。

什么是 link rel="prefetch",它真能“取数据”吗
不能。link rel="prefetch" 不会执行脚本、不触发 API 请求、不解析 HTML 或 JSON,它只做一件事:在浏览器空闲时,把指定的资源(通常是 JS、CSS、HTML 文档)下载并存入 HTTP 缓存。后续导航或资源加载时,若匹配缓存键,就能复用——但它不会主动“取数据”供 JS 直接读取,也不提供回调或 Promise。
link rel="prefetch" 的正确写法和生效条件
必须满足三个前提才可能触发预取:
- 资源 URL 必须同源(协议、域名、端口一致),跨域会静默忽略
- 必须放在
中,且在首次渲染前已存在 DOM(动态插入的link大多无效) - 浏览器需处于空闲状态(无高优先级请求、CPU/网络负载低),且当前页面生命周期未结束(比如还没跳转或关闭)
典型写法:
as 属性必须准确标注资源类型,否则可能降级为低优先级 fetch,甚至被忽略;as="fetch" 是无效值,不要写。
立即学习“前端免费学习笔记(深入)”;
为什么你写了 prefetch 却没看到 network 请求
常见原因包括:
- Chrome 仅在用户可能导航到该页面(如页面含对应
)时才提升 prefetch 优先级,纯静态 prefetch 可能延迟数秒甚至跳过 - DevTools 的 Network 面板默认过滤掉“prefetch”类型的请求,需勾选
prefetch或取消所有过滤器才能看到 - 资源已被强缓存(
Cache-Control: immutable或 max-age 很大),浏览器直接从磁盘缓存读取,不发新请求 - 使用了
rel="preload"混淆概念——preload是高优先级强制加载,prefetch是低优先级投机加载,二者不可互换
想真正“预取数据”,该用什么替代方案
如果目标是提前获取 JSON、API 响应等可被 JS 使用的数据,prefetch 不适用。可行路径有:
- 页面加载后,用
fetch()+cache.put()手动存入 Cache API,后续通过cache.match()读取 - 对关键接口,在服务端启用 HTTP/2 Server Push(已逐步弃用)或 HTTP/3 的 QPACK 推送能力(需服务器支持)
- 在 SPA 中,路由切换前用
fetch()预加载下一页所需数据,配合 Suspense 或 loading 状态管理 - 利用
rel="prerender"(仅 Chromium 支持)预渲染整个页面,但开销大、兼容性差,且不适用于数据驱动场景
真正容易被忽略的是:预取的价值高度依赖用户行为预测。没有点击流分析或埋点反馈支撑的 prefetch,往往只是往缓存里塞了一堆没人用的字节。











