rel="preload" 是声明式下载提示,只提升CSS下载优先级,不解析、不阻塞渲染、不改变样式应用时机;必须配as="style"、onload挂载、crossorigin(如需跨域),且不能替代rel="stylesheet"。

rel="preload" 是什么,不是什么
rel="preload" 是一个声明式提示,告诉浏览器“这个 CSS 很重要,马上下载”,但它**不执行解析、不阻塞渲染、不改变样式应用时机**。很多人误以为加了它就能让样式“提前生效”,其实它只管下载——CSS 文件仍会在 DOMContentLoaded 前或 load 时按常规规则参与渲染流程。
常见错误现象:rel="preload" 后样式依然闪动、首屏文字短暂无样式;或者误用 rel="prefetch" 导致资源被低优先级加载,完全没效果。
- 只对当前页面确定会用的 CSS 用
rel="preload",比如首屏关键 CSS(critical.css) - 不能替代
rel="stylesheet":必须同时保留原始 link 标签,否则样式不会应用 - 必须指定
as="style",否则浏览器无法正确设置请求优先级和 CORS 行为 - 不要 preload 整个
main.css—— 它体积大、非关键部分多,反而挤占带宽
怎么写才真正触发高优先级下载
关键不在有没有 rel="preload",而在是否满足浏览器的“可信预加载”条件。漏掉任一条件,它就会退化成普通 fetch,失去意义。
- 必须有
as="style",且不能拼错(如写成as="css"或漏掉) - 必须加
onload回调,把 preload 的 CSS 动态挂载为有效样式表,否则只是下完就丢 - 如果 CSS 有跨域请求(比如 CDN 上的字体或图片),必须加
crossorigin属性,否则会因 CORS 失败静默失败 - 路径必须准确:相对路径以当前 HTML 为基准,不要假设和
stylesheet的 base 一致
示例(正确):
立即学习“前端免费学习笔记(深入)”;
<link rel="preload" href="/css/critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'" crossorigin>
注意:this.onload=null 是防重复执行的关键,否则在某些缓存场景下可能触发两次 rel 切换。
为什么用了 preload 还是白屏或 FOUC
FOUC(Flash of Unstyled Content)或白屏,往往不是 preload 没生效,而是它和实际样式应用之间存在逻辑断层。
- preload 的 CSS 如果含
@import或异步加载的字体,这些子资源不会被自动提升优先级,仍可能延迟渲染 - 如果页面 JS 在 DOM 构建后才动态插入内容,而 preload 的 CSS 没覆盖那些元素的选择器,照样无样式
- 服务端渲染(SSR)场景下,若 critical CSS 没内联,仅靠 preload 下载 + 异步挂载,中间存在样式空窗期
- Chrome 120+ 对
preload的资源启用更激进的取消策略:若 3 秒内未被使用(比如 onload 未及时触发),会中止请求
简单验证方式:打开 DevTools → Network → 找到该 CSS 请求,看 Initiator 列是否为 preload,Priority 是否为 Highest;再看 Timing 里是否出现 Stalled 或长时间 Waiting (TTFB)。
要不要配合 media 或 disabled 控制加载时机
可以,但要小心副作用。浏览器对 media 属性的处理会影响 preload 是否触发。
-
media="print"或media="(min-width: 992px)"等非匹配值下,rel="preload"会被忽略(Chrome/Firefox 行为一致) - 想实现“只在移动端 preload”,得用 JS 动态创建 link,而不是静态写死
media -
disabled属性对 preload 无效;它只影响已挂载的stylesheet,不能用来控制 preload 本身 - 如果需要条件加载(比如用户偏好深色模式),建议用 JS 判断后动态 insert,比依赖 media 更可控
真正省事又安全的做法:把关键 CSS 内联,非关键部分用 rel="preload" + onload 挂载,不折腾 media 分支。
容易被忽略的一点:preload 的 CSS 若含 font-face,字体文件本身不会被自动 preload,得单独为每个 url() 加一条 preload,否则文字仍会等字体就绪才渲染。










