Preload只对首屏急需但浏览器发现太晚的资源有效,如CSS中@font-face字体、内联style的hero图、模块化JS主chunk及<picture>关键source;错用会抢带宽拖慢首屏。

link rel="preload" 不是加了就快,而是加对了才快——它只对浏览器“发现太晚但首屏立刻要用”的资源有效,加错或滥用反而抢带宽、拖慢首屏。
哪些资源真该用 preload?
浏览器只能自动发现 <img>、<script src>、<link rel="stylesheet"> 里的资源。以下几类常被“藏”着,等解析完 CSS 或 JS 才暴露,导致 FOIT、FOUC 或首屏图延迟:
- CSS 中
@font-face引用的字体(尤其.woff2),不预加载就等解析完 CSS 才发起请求 - 内联
<style>里用background-image加载的 Hero 图,parser 根本看不到 URL - 紧跟在
<script type="module">后面、但没显式src的主 chunk(如app.js),模块执行前必须就位 - 首屏
<picture>中关键<source>对应的 WebP/JPEG,srcset是运行时解析的
别对 analytics.js、非首屏轮播图、第三方 widget 脚本用 preload——它们不参与首屏渲染,纯属带宽干扰。
as 属性写错等于白写
as 不是可选装饰,它直接决定请求头、CORS 策略、缓存分区和优先级。漏写或写错,preload 就退化成普通 fetch,Priority 显示 Low,和没写一样。
立即学习“前端免费学习笔记(深入)”;
-
as="font"→ 必须同步加crossorigin,否则 Chrome/Safari 加载完也丢弃(即使同源) -
as="style"→ 必须配onload="this.onload=null;this.rel='stylesheet'",否则只下载不生效 -
as="script"→ 若后续仍用<script src>引同一 URL,能复用;但若有integrity,preload也得带上,否则缓存不匹配 -
as="image"→ 不支持srcset或sizes,只适合确定尺寸/格式的单图;对普通<img src>无效,不如直接设fetchpriority="high"
怎么验证 preload 真起作用了?
别只看 HTML 里有没有那行代码。打开 Chrome DevTools → Network 面板 → 刷新页面 → 按资源名筛选后重点看三列:
-
Initiator:必须显示
preload,不是parser或script -
Priority:字体/JS 应为
Highest,CSS/图片应为High;若显示Medium或Low,大概率是as没写或写错 -
Start Time:对比未加
preload时同资源的起始时间,理想提前 200–600ms;若看到pending或canceled,可能是 HTTP/2 Push 已发,或preconnect没就绪就发了请求
特别注意 Safari:对 as="font" 的 crossorigin 更严格,漏写或写成 crossorigin="" 都可能失效。
preload 和 prefetch、preconnect 别混用
三者用途完全不同,混用等于浪费资源:
-
preload:「我马上就要用这个资源,现在就去取」→ 当前导航生命周期内必用,高优抢占带宽 -
prefetch:「用户可能点进下一页才需要,空闲时悄悄下」→ 低优先级,可被丢弃,不能用于首屏资源 -
preconnect:「我要连这个域名,先建好 TCP/TLS,省得后面卡握手」→ 只写域名,不指定路径,比如https://cdn.example.com
典型组合是:preconnect 到 CDN 域名 + 同时 preload 具体字体文件;对 API 域名只 preconnect,别 preload 某个接口 URL——HTTP 请求不可预加载。
最容易被忽略的点是:字体没加 crossorigin、CSS 预加载后忘了用 onload 切换 rel、路径含查询参数却没保持完全一致(?v=1.2.3 和 ?v=1.2.4 缓存不命中)。这些细节一错,preload 就从提速利器变成负优化开关。



















