该用preload而非prefetch时:当前页面渲染中“马上就要用、但浏览器默认发现太晚”的资源,如CSS中@font-face引用的字体或首屏JS动态import的模块;而prefetch仅适用于用户离开后大概率访问、且不参与当前渲染的后续页面资源。

什么时候该用 preload,而不是 prefetch
当前页面渲染过程中「马上就要用、但浏览器默认发现太晚」的资源,必须用 preload。比如 CSS 里 @font-face 引用的 iconfont.woff2,或首屏 JS 动态 import() 的模块入口文件。
常见误用包括:
- 对已加
defer或type="module"的主脚本再preload:它已有调度逻辑,preload只会多发一次 high 优先级请求,挤占 HTTP/2 流 - 用
as="image"preload<img srcset>中某张图:srcset是运行时解析的,preload无法命中,纯属白占带宽 - 漏写
crossorigin加载跨域字体:请求发出但响应被丢弃(无报错),FOIT 持续,而 high 优先级带宽已被占用
验证是否生效:Chrome DevTools → Network → 刷页面 → 筛选该资源 → 看 Priority 列是不是 High;不是,基本就是 as 写错或路径 404。
什么时候该用 prefetch,而不是 preload
用户离开当前页后「大概率访问、且不参与当前渲染」的资源,才适合 prefetch。典型场景是 SPA 路由切换前预取下一页的 chunk,比如首页点击「商品详情」前,prefetch product-detail.js。
立即学习“前端免费学习笔记(深入)”;
容易踩的坑有:
- 把首页 banner 图设成
rel="prefetch":浏览器真等到window.onload后才拉,首屏 LCP 直接拖慢 300ms+ -
href写协议相对路径(如//cdn.example.com/xxx.js):被当成非法协议直接丢弃,Network 里根本看不到请求 - 没配
Cache-Control: public, max-age=31536000:下次跳转仍要重下,预取失效,上次带宽白费 - 误以为
prefetch能复用preload缓存:不能。两者缓存分区隔离,preload进的是当前页专用缓存,prefetch走常规 HTTP 缓存
Firefox 默认关闭 prefetch,需手动设 network.prefetch-next = true;Safari 对非脚本类资源(如 HTML、图片)支持极弱,甚至忽略。
preload 和 prefetch 同时存在,会抢带宽吗
它们不在同一调度队列竞争:preload 进「高优渲染队列」,prefetch 进「后台空闲队列」,所以不会直接互抢。真正的问题是「preload 用错了对象」。
例如把本该 prefetch 的商品页 JS 写成 preload,它就会和首页 CSS 争 Highest 优先级,导致关键样式延迟解析,LCP 延后。
硬性事实:
-
preload的as值决定 CORS 行为:as="font"强制要求crossorigin,as="script"则不强制 -
prefetch不需要as,但建议加上(如as="script"),否则浏览器只能靠 MIME 推断,可能降级处理 - 同一资源既
preload又prefetch,Chrome 会发两次请求,纯属浪费
验证 prefetch 是否真发起请求
DevTools Network 面板搜不到 prefetch 请求,不等于没生效,更可能是被策略拦截或条件未满足。
先查这三件事:
- 页面是否已触发
load事件?若有长任务阻塞主线程,prefetch就不会启动 - Network Filter 输入
prefetch,勾选 “All”,找initiator: Other且Priority: low的条目 - 目标资源是否同源?部分浏览器对跨域
prefetch支持有限,且不报错
最常被忽略的一点:prefetch 的「空闲」是真实空闲——CPU 负载低、网络未拥塞、没开省流模式、内存够用。任意一项不满足,它就安静等待,连请求都不会发。



















