必须配对onload才能让css生效,因为rel="preload"仅下载不解析、不挂载,需onload动态将rel改为stylesheet以触发cssom构建;漏写as="style"或路径不一致会导致降级加载或缓存失效。

为什么必须配对onload才能让CSS生效
只写<link rel="preload" href="main.css" as="style">,CSS根本不会应用——它只是下载进缓存,不解析、不参与渲染树构建。浏览器不会自动把预加载的 CSS 当成样式表处理。
常见错误是额外再写一个<link rel="stylesheet" href="main.css">,结果因路径细微差异(比如/css/main.css vs css/main.css)触发二次请求,首屏反而更慢。
正确做法是用onload动态切换rel属性:
<link rel="preload" href="/css/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
-
this.onload=null防止重复触发(尤其在缓存命中时可能回调多次) - 路径必须为绝对路径,避免子页面中相对路径解析失败
- 不要在
里写这个<link>,否则 parser 已进入 body 阶段,preload 被忽略
as="style"漏写或写错的后果比你想象的严重
漏掉as="style",或写成as="stylesheet"、as="css",浏览器就当普通 fetch 处理:Priority 降为Low,Initiator 显示为(other),Network 面板里看不到提前下载时间点。
as="style"不是提示,是强制契约,它决定三件事:
- 请求头带
Accept: text/css,匹配服务端 MIME 响应 - 进 CSS 缓存池,后续
<link rel="stylesheet">能直接复用 - 触发高优先级调度,通常比普通资源早 200–600ms 开始下载
验证是否生效:Chrome DevTools → Network → 筛选Initiator: preload,Priority 列应为High,状态码为200且 Timing 中 Start Time 明显靠前。
容易被忽略的路径与位置陷阱
preload 的位置和路径容错率极低,两个细节一错,整条链就断了:
- 必须紧贴
<meta charset>之后,或<title></title>之前;写在<link rel="stylesheet">下面、JS 块之后、里,全部无效 - href 必须与后续实际使用的路径完全一致(包括斜杠开头与否、大小写、查询参数),哪怕多一个
/,缓存就不命中 - 如果项目部署在子路径(如
https://example.com/app/),href 得写/app/css/main.css,不能只写css/main.css
动态插入(如document.createElement('link'))完全无效——preload 是 parser-blocking 阶段行为,运行时添加等于没写。
什么情况下不该用preload加载CSS
不是所有 CSS 都适合 preload。滥用反而拖慢首屏:
- 已内联在
里的关键 CSS:再 preload 外部文件会造成冗余 - 放在
底部的非关键 CSS(如打印样式、主题切换 JS 控制的样式):用户根本不会立刻用到 - 被
<link rel="stylesheet" media="print">等条件加载的 CSS:preload 不识别 media,会强行拉取 - HTTP/2 Server Push 已启用的环境:preload 请求可能被静默跳过,得关掉 Push 或改用其他策略
真正值得 preload 的,只有「首屏渲染链上缺失的高优依赖」:比如 HTML 内联了部分样式,但主样式表在底部才引入;或者某个关键组件的 scoped CSS 单独拆包,又必须在首屏立即生效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











