preload进当前页专用高优资源池,生命周期绑定本次导航;prefetch进长期http缓存,按cache-control存续。二者路径隔离、不可复用,触发时机、优先级、缓存机制均不同。

Preload 和 Prefetch 在浏览器缓存系统中根本不是“进同一个池子”,它们各自走完全独立的缓存路径,底层机制和生命周期也截然不同。
Preload 进的是“当前页高优资源池”
它不进常规 HTTP 缓存,而是进入一个专为本次导航(navigation)服务的临时资源池。这个池子只对当前页面生命周期有效,页面卸载后资源就丢弃,哪怕 URL 完全相同也不会被后续页面复用。
- 触发时机极早:HTML 解析阶段就发起请求,优先级为 Highest 或 High,会抢占带宽
- 必须带 as 属性(如
as="font"),否则可能降级为普通 fetch,无法参与渲染关键路径 - 加载完成即可用,但不会自动执行或应用(比如预加载的 CSS 不会自动生效,仍需
<link rel="stylesheet">引入) - 即使目标资源有强缓存头,Preload 也只管本次页面——它不依赖 Cache-Control,也不受其限制
Prefetch 进的是“长期 HTTP 缓存”
它走标准的 HTTP 缓存流程,下载的资源会被存入主磁盘/内存缓存区,按 Cache-Control 等响应头决定是否可复用、保留多久。但前提是:资源本身得允许被缓存。
- 触发时机很晚:必须等
window.onload完成、主线程空闲、网络无高优任务时才尝试发起 - 优先级为 Low,容易被跳过(省流模式、内存紧张、2G 网络、页面提前跳转都会导致不发请求)
- as 属性不是可选的:写错或缺失会导致请求降级,甚至静默失败——浏览器不知道该加什么 Accept 头、是否要 CORS,也就无法正确存入对应缓存槽位
- 若响应头是
Cache-Control: no-store或no-cache,浏览器连缓存都不建,Prefetch 直接失效
两者缓存不可互通,也不能互相替代
同一个 /main.woff2 文件,用 Preload 加一次、Prefetch 加一次,浏览器会分别存两份,互不感知。因为 Preload 的资源没走 HTTP 缓存校验逻辑,而 Prefetch 的资源又没进 Preload 那个“马上要用”的调度队列。
- 想让字体在首屏立刻渲染?用
<link rel="preload" as="font" crossorigin> - 想让用户点“下一步”时秒开?且该资源已设
public, max-age=31536000?再加一条<link rel="prefetch" as="script" href="/next-page.js"> - 别把 Prefetch 当 Preload 用——它不会提升首屏性能;也别指望 Preload 能为下个页面省流量——它压根不进长期缓存
验证是否真进了缓存池
别只看 Network 面板默认标签页。Chrome DevTools 中要打开 Network → 右上角过滤器输入 is:prefetch 才能看到 Prefetch 请求;Preload 请求则通常标记为 Priority: Highest 或出现在 HTML 解析早期。
- Prefetch 没出现?先确认 onload 是否已触发、页面是否稳定停留超 1s、是否开了省流模式
- Preload 加了但字体还是闪?检查是否漏了
crossorigin(字体跨域必需)、as="font"是否拼写正确、WOFF2 MIME 类型是否匹配











