preload必须写在<head>中<meta charset>之后、<title>之前,动态插入完全无效;as属性必须准确匹配资源类型(如font/css/script/image),否则降级为低优先级fetch请求。

preload必须写在最前面,动态插入完全无效
浏览器只在 HTML 解析初期(parser 阶段)识别 rel="preload",一旦开始构建 DOM 或进入 <body>,后续的 <link rel="preload"> 就被忽略。JS 动态创建并 append 的标签,比如 document.createElement('link'),根本不会触发预加载。
常见错误是把它塞在 <link rel="stylesheet"> 后面、<title> 下方,甚至放在 <body> 里——结果首屏字体或关键图片延迟 200ms+,LCP 直接恶化。
- ✅ 正确位置:
<meta charset="utf-8">紧跟其后,或<title>前 - ❌ 错误位置:
<body>内、JS 脚本块之后、CSS 引入下方 - ⚠️ 注意:多个 preload 按书写顺序发起请求,但优先级由
as决定,不是靠“抢位置”
as 属性必须准确填写,漏写或错写等于没写
as 不是提示,是强制声明资源类型。浏览器靠它决定请求头、CSP 策略、缓存分区和优先级。填错或不填,Initiator 列会显示为 (Other),Priority 降为 Low,Network 面板里请求可能 Pending 或直接消失。
- 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 正确做法:
<link rel="preload" href="main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">,且必须加this.onload=null防重复触发 - 字体无需手动切换,但必须带
crossorigin,否则 Chrome/Safari 加载完也会丢弃 - 不要对已由浏览器自动发现的资源重复 preload,比如
<img src="logo.png">—— 改用fetchpriority="high"更简单有效
哪些资源该 preload,哪些千万别碰
preload 是给“浏览器发现太晚但首屏立刻要用”的资源用的。浏览器能自动发现 <img>、<script src>、<link rel="stylesheet">,但对以下几类常“藏”在 CSS 或 JS 里的资源无能为力:
- ✅ 该用:
@font-face引用的 .woff2 字体、内联<style>中的background-image、首屏<picture>的关键<source>、紧随<script type="module">后的主入口 JS - ❌ 别碰:
analytics.js、非首屏轮播图、第三方 widget、懒加载模块的 JS、print.css(媒体不匹配) - ⚠️ 特别注意:不要对
chunk-vendors.xxx.js或路由级 chunk 用 preload —— 它们不参与首屏渲染,纯属抢带宽
Initiator 是 preload、Priority 是 Highest 或 High、且下一页复用时能命中 200 (from memory cache)。路径拼写、HTTP 状态码、缓存头(如 Cache-Control: no-store)任一出错,预加载就白做了。



















