preload必须写在<meta charset>后、<title>前,否则完全失效;as属性必须精准匹配资源类型(如as="script"/as="font"/as="image"),漏写或错写将退化为低优先级fetch请求。

preload必须写在最前面,否则完全失效
浏览器只在 HTML parser 阶段识别 rel="preload",一旦开始构建 DOM 或进入
<link rel="preload"> 就被忽略。动态用 JS 插入(比如 document.createElement('link'))根本不会触发预加载。
常见错误位置包括:<link rel="stylesheet"> 后面、<title> 下方、甚至塞进 <body> 里——结果首屏字体或关键图延迟 200ms+,LCP 直接恶化。
-
<meta charset="utf-8">紧跟其后,或<title>前是唯一安全位置 - 多个
preload按书写顺序发起请求,但优先级由as决定,不是靠“抢位置” - 如果组件是服务端渲染(SSR)生成的,确保模板中该标签位于
<head>早期;如果是客户端渲染(CSR),不能依赖 JS 注入
as 属性写错等于没写,必须严格匹配资源类型
as 不是提示,是强制声明。浏览器靠它决定请求头、CSP 策略、缓存分区和优先级。漏写或填错(如 as="javascript"),rel="preload" 就退化为普通 fetch,Network 面板里 Initiator 显示 (Other),Priority 降为 Low。
- CSS 文件 → 必须
as="style"(不是"stylesheet") - 字体(.woff2/.woff)→
as="font"+crossorigin(同源也必须加) - JS 脚本 →
as="script"(模块脚本也用这个,不用配type="module") - 图片 →
as="image"(as="img"或as="picture"全部无效) - JSON 接口 →
as="fetch",且响应头需含Access-Control-Allow-Origin
preload 只下载不执行,CSS 和字体要额外处理
<link rel="preload" href="main.css" as="style"> 只负责下载,不会解析、不会应用。如果再写一个 <link rel="stylesheet" href="main.css">,路径稍有差异(比如斜杠、大小写、查询参数),就会触发二次请求。
立即学习“前端免费学习笔记(深入)”;
- CSS 需配
onload="this.onload=null;this.rel='stylesheet'"才能转为生效样式 - 字体需在 CSS 中配合
@font-face的font-display: swap,否则仍 FOIT - JS 脚本若后续仍用
<script src>引同一 URL,能复用;但若有integrity,preload也得带上,否则缓存不匹配 - 图片
as="image"不支持srcset或sizes,只适合确定尺寸/格式的单图;对普通<img src>无效,不如直接设fetchpriority="high"
组件级预加载容易踩的坑:路径、缓存、条件判断
组件常带动态路径(如 href="/assets/${name}.webp")、运行时 media 查询、AB 实验分支等,这些都会让预加载失效或重复。
- 相对路径必须基于 HTML 文件位置计算,建议统一用根相对路径(
/images/hero.jpg)或绝对路径 - HTTP 缓存头必须允许缓存(如
Cache-Control: public, max-age=31536000),否则预加载结果无法复用 - 用
media属性做条件预加载(如media="(min-width: 768px)")时,确保与实际使用场景一致,避免白下 - 不要同时
preload和prefetch同一资源,Chrome 会发两次请求 - 验证是否生效:打开 Chrome DevTools → Network 面板,筛选资源名,确认
Initiator是preload,Priority是Highest或High
preload 当成“加了就快”的开关。真正起效的前提是:路径精准、as 正确、位置合规、后续真实使用——缺一不可。



















