rel="preload"必须置于<meta charset>后、<title>前,且as属性须严格匹配资源类型并配齐crossorigin等要求,否则将降级为低优先级请求或失效。

rel="preload"必须写在最前面,否则可能错过最佳加载窗口
浏览器一解析到 <link rel="preload"> 就发起请求,不等 DOM 构建完成。如果它被放在 <link rel="stylesheet"> 后面、或 <title> 之后,字体或首屏图的下载可能比理想时间晚 200–400ms——尤其在弱网下,这直接导致 FOIT 或 LCP 延迟。
常见错误包括:用 JS 动态插入 <link>、把 preload 放在 <body> 里、或塞在第三方 CSS 引入之后。
- ✅ 正确位置:
<meta charset>后、<title>前 - ❌ 错误位置:
<script>标签后、<style>块内、任何<body>子节点中 - ⚠️ 注意:即使路径和
as都对,放错位置也会让预加载“赶不上趟”
as 属性写错或漏写,preload 就等于没写
as 不是可选提示,而是浏览器调度资源的唯一依据。漏写、写成 as="javascript" 或 as="font/woff2",都会让请求降级为 Priority: Low,和普通 fetch 无异。
典型匹配关系必须严格对应:
立即学习“前端免费学习笔记(深入)”;
- CSS 文件 →
as="style"(不是"stylesheet") - 字体 →
as="font"+ 必须带crossorigin(同源也得加) - JS 脚本 →
as="script"(模块脚本也用这个,不是"module") - 图片 →
as="image"(只适用于确定尺寸/格式的单图,不支持srcset) - 关键 JSON →
as="fetch"+ 配crossorigin(默认带凭据)
错误示例:<link rel="preload" href="/main.js" as="javascript"> —— 浏览器直接忽略该标签。
preload 对 video 和 audio 的预加载效果极有限
as="video" 或 as="audio" 只触发 HTTP 下载,不触发解码,也不影响 <video> 元素的 readyState。iOS Safari 中基本无效,且无法复用缓存。
常见误用:
- 跨域视频没加
crossorigin→ 请求发出去但响应被丢弃(Network 面板状态码为 0) - 服务端没返回
Access-Control-Allow-Origin→ CORS 拦截,缓存失败 - 写了
<link rel="preload">却没在 HTML 里声明<video>→ 资源进了缓存,但元素根本不知道有这回事 - 指望 preload 后直接调
play()→ 大概率报DOMException: The element has no supported sources
真正可控的做法:确保 <video> 在初始 HTML 中存在(哪怕 display: none),配 preload="metadata" + faststart 视频 + Accept-Ranges: bytes,<link preload> 仅作为同域下的带宽抢跑补充。
别拿 preload 当 prefetch 用,否则拖慢当前页
rel="preload" 是给“当前页马上要用”的资源用的;rel="prefetch" 才是给“下一页可能用”的资源准备的。混用会抢带宽、压低首屏优先级,甚至引发白屏。
典型翻车场景:
- 对
analytics.js、非首屏轮播图、第三方 widget 加preload→ 完全不参与首屏渲染,纯属干扰 - 用
preload加下一页的 HTML(如product.html)→ 浏览器立刻拉取,挤占关键资源带宽 - 对懒加载模块 JS 做
preload→ 浏览器无法静态分析依赖,preload 不会被触发,还浪费连接
验证时看 Network 面板的 Initiator 列:preload 应该出现在当前页生命周期内,且 Priority 是 Highest 或 High;如果看到 Priority: Low 或 Initiator: parser,基本就是用错了。
真正难的不是写那行代码,而是判断“这个资源是不是真被浏览器‘发现太晚但首屏立刻要用’”。路径、as、crossorigin、服务端响应头、缓存策略,缺一不可——任何一个环节断掉,rel="preload" 就只是 HTML 里一行安静的注释。



















