preload 是“马上就要用”,浏览器解析到即发起高优先级请求,适合首屏关键但发现太晚的资源;prefetch 是“可能要用”,onload 后空闲加载,属预测性缓存。

preload 是“马上就要用”,解析到就发请求
浏览器一遇到 <link rel="preload"> 就立即发起高优先级请求,不管 DOM 是否构建完、CSS/JS 是否加载,只要 HTML 解析器扫到它,就抢带宽。适合首屏必须、但发现太晚的资源,比如 @font-face 引用的 .woff2、内联 CSS 里的关键背景图、import() 即将加载的 JS chunk。
常见错误包括:
-
as属性漏写或写错(如as="fonts"或as="font"拼错),浏览器直接降级为低优先级 fetch,Network 面板里 Priority 显示为Low,等于白加 - 字体资源没加
crossorigin,Chrome/Safari 下载完也不应用,且控制台不报错,只表现为 FOIT 或空白 -
preload放在<body>里或动态插入(如document.createElement('link')),浏览器根本不识别 -
as="style"必须配onload="this.onload=null;this.rel='stylesheet'",否则只下载不解析
prefetch 是“可能要用”,onload 后才空闲加载
<link rel="prefetch"> 不是“提前加载”,而是“预测性缓存”。它等整个页面 window.onload 触发、主线程空闲后才启动,优先级为 Low,且可能被浏览器跳过——比如用户开了省流模式、内存紧张、网络是 2G,或快速切走了页面。
典型使用场景有:
立即学习“前端免费学习笔记(深入)”;
- SPA 中首页 prefetch 下一页的
detail.js,前提是用户点击「商品列表」后大概率进详情页 - 搜索页 prefetch 搜索结果页的 bundle,而不是首页就 prefetch 所有二级页
- href 必须是绝对路径或根相对路径(如
/js/next.js),协议相对路径(//cdn.com/a.js)会解析失败 - Firefox 默认禁用 prefetch(
network.prefetch-next = false),Safari 对非脚本类资源(如.css、.jpg)支持极弱
同一个 URL 既 preload 又 prefetch,会发两次请求
Chrome 会分别走两个通道:preload 进“当前导航高优资源池”,生命周期绑定本次页面;prefetch 进“长期 HTTP 缓存”,按 Cache-Control 存。即使 URL 完全相同,也无法复用。
后果很实在:
- 浪费带宽和连接数,尤其当
preload抢占了critical.css的带宽时,LCP 可能拖慢 300ms - 如果 prefetch 目标资源没设强缓存(如缺
Cache-Control: public, max-age=31536000),下次访问仍要重下,白忙一场 - 服务端日志里会出现两条独立请求记录,不是缓存命中
as 属性决定 preload 是否生效,而 prefetch 几乎不依赖它
as 对 preload 是强制项:它告诉浏览器该资源的类型,从而设置正确请求头、CORS 行为、缓存分区和优先级。没有 as,preload 就只是个普通 fetch。
prefetch 不强制要求 as,浏览器会根据 URL 后缀自动推断类型;但加上更稳妥,尤其当 URL 无扩展名(如 /api/chunk?id=123)时,as="script" 能避免 MIME 类型误判。
容易忽略的一点:as="image" 不支持 srcset 或 sizes,只适用于尺寸/格式确定的单图;对普通 <img src> 无效,别指望它加速懒加载图。



















