rel="preload" 单独使用无效,仅下载不应用CSS;必须配合as="style"、onload切换rel及noscript降级才能确保样式生效且兼容。

rel="preload" 本身不会让 CSS 生效,只下载不应用——必须配合 as="style" 和 onload 动态切换 rel,否则页面白屏或样式错乱。
为什么 rel="preload" 单独写没用
浏览器看到 ,只会发起请求、存进缓存,但完全不解析、不挂载、不参与渲染。DOM 还是无样式的,首屏可能空白或布局坍塌。
-
as="style"必须显式声明:缺了它,Chrome/Firefox 会降级为as="fetch",优先级变低,还可能被 CSP 拦截 - Safari 在 iOS 16.4 / macOS 13.3 之前根本不识别
as="style",rel="preload"被静默忽略 - HTTP 响应头含
Cache-Control: no-cache时,Chrome 会跳过预加载(认为没必要)
正确写法:preload + onload 切换 + noscript 降级
这是目前兼容性最好、行为最可控的最小可行路径。
- 必须写
onload="this.onload=null; this.rel='stylesheet'":第一句防重复执行(Chrome 某些版本onload可能触发两次),第二句才真正启用样式 -
href路径必须和后续实际使用的完全一致(包括查询参数,theme.css?v=2.1和theme.css?v=2.2是两个资源) -
不是可选项,是必要兜底:JS 禁用或旧浏览器里,没有它就等于关键样式不存在
示例:
<link rel="preload" href="/css/critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link rel="stylesheet" href="/css/critical.css"></noscript>
容易踩的坑:重复加载、媒体查询、验证方式
同一个 CSS 文件不能既被 preload 又被普通 引用,否则 Chrome Network 面板会显示两次请求,浪费带宽。
-
media属性控制“是否下载”,不是“是否应用”:写media="(min-width: 768px)",小屏设备根本不会发请求;但已下载的资源不会因 media 变化自动应用 - 验证是否生效,别只看 Network 里有没有 200:要进 Elements 面板确认对应
的rel已变成stylesheet;Performance 面板里看 Stylesheets 解析时间是否前移;禁用 JS 后刷新,确认页面仍有样式 - 不要用
onreadystatechange替代onload:它在现代浏览器中不可靠,且无法区分成功/失败
真正难的不是写那行 preload,而是确保它在 Safari、旧 WebView、JS 禁用、CDN 缓存策略变更等所有边界条件下,都不导致白屏或样式丢失。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











