rel="preload"单独使用无效,因只下载不解析应用,必须配合as="style"、onload切换rel为stylesheet及降级,否则白屏或样式错乱。

不能只靠 rel="preload" 实现“异步加载”——它只下载不应用,漏掉后续步骤会白屏或样式错乱。
为什么 rel="preload" 单独写没用
浏览器看到 <link rel="preload" href="main.css" as="style">,只会提前发起请求、把文件拉到缓存,但完全不解析、不挂载、不参与渲染。DOM 还是无样式的,页面可能空白或布局坍塌。
- 常见错误写法:
<link rel="preload" href="base.css" as="style">后面没跟任何<link rel="stylesheet"> -
as="style"必须写,否则 Chrome/Firefox 会降级为普通fetch,不设高优先级,也不校验 MIME 类型 - Safari(iOS 16.4 / macOS 13.3 之前)根本不支持
as="style"的preload,只当普通资源下载,毫无预加载效果
preload + onload 动态切换 rel 是最简可行路径
这是目前兼容性最好、行为最可控的方案,核心是让 preload 下载完成后,立刻把同一个 <link> 变成生效的样式表。
- 必须写
onload="this.onload=null; this.rel='stylesheet'":第一句防重复执行(Chrome 某些版本 onload 可能触发两次),第二句才真正启用样式 -
href路径必须和后续实际使用的完全一致(包括查询参数,theme.css?v=2.1和theme.css?v=2.2是两个资源) - 不要用
onreadystatechange替代onload——它在现代浏览器中不可靠,且无法区分成功/失败
<link rel="preload" href="critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link rel="stylesheet" href="critical.css"></noscript>
必须配 <noscript></noscript> 降级,否则 JS 禁用时样式彻底丢失
rel="preload" 在 IE 全系、旧版 Android WebView、或用户手动禁用 JS 时会被静默忽略——没有 fallback 就等于关键样式不存在。
-
<noscript></noscript>不是可选项,是必要兜底:JS 不可用时,退回到传统阻塞式加载,至少功能完整 - 别指望
prefetch或preconnect替代它——前者优先级低、不保证下载时机,后者根本不加载资源 - 若服务端对 CSS 返回
Cache-Control: no-cache,Chrome 会跳过 preload(认为没必要预取),需检查响应头
非关键 CSS 里藏了字体或大图,异步也救不了首屏
就算你把 non-critical.css 延迟加载了,如果它里面写了 @font-face 引了一个 2MB 的 woff2,或 background-image 指向高延迟 CDN 图片,这些子资源会在该 CSS 挂载后才开始拉取——直接挤占首屏 JS/CSS 带宽。
- 检查非关键 CSS 是否含
@import:它会同步阻塞该 CSS 解析,形成隐蔽二级阻塞链 - 字体必须加
font-display: optional,图片建议加loading="lazy"缓解 - 避免在非关键 CSS 里写
@import——截至 2026 年 5 月,它仍是被低估的性能雷区
真正难的不是写对那行 preload,而是判断哪些 CSS 算“关键”、哪些资源藏在样式表底下、以及降级逻辑是否覆盖所有 JS 禁用场景。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











