CSS阻塞渲染因样式直接影响布局,浏览器强制同步构建CSSOM;JS可通过async/defer异步,而CSS无类似开关。优化核心是关键CSS内联或preload,非关键CSS用media属性延迟解析。

为什么CSS阻塞渲染,而JS还能异步?
浏览器遇到 会立即暂停 HTML 解析,等 CSSOM 构建完才继续。这不是“慢”,是强制同步——因为样式直接影响布局和绘制,浏览器不敢冒风险。而 <script></script> 默认也阻塞,但加 async 或 defer 就能绕开,CSS 没这种开关。
所以优化核心不是“让CSS更快”,而是“让关键CSS更快可用,非关键CSS不拖后腿”。
- 首屏必须的样式(如导航、标题、按钮)要内联或提前加载
- 主题色、动画、打印样式等非关键CSS,用
media属性延迟解析(比如media="print"的样式不会阻塞屏幕渲染) - 避免在
里堆多个,每个都触发一次网络请求+解析阻塞
如何用rel=preload提前抓取关键CSS?
rel="preload" 不是替代 ,而是“提前喊浏览器去拿”,它本身不解析、不应用,得配 onload 手动挂载。漏掉这步,就只是白下了一个文件。
<link rel="preload" href="critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link rel="stylesheet" href="critical.css"></noscript>
-
as="style"必须写,否则浏览器不会按高优先级加载 CSS 资源 -
onload回调里要立刻把rel改成stylesheet,否则样式永不生效 - 记得加
降级,否则禁用 JS 的用户看不到关键样式 - 不要对所有 CSS 都
preload——只对首屏渲染必需的那部分(通常 ≤ 10KB)
link标签的media属性怎么真正起效?
media 不是“加载条件”,而是“应用条件”。浏览器仍会下载 media 不匹配的 CSS,只是不解析、不构建 CSSOM。比如 media="(max-width: 768px)" 在桌面端也会下载,但不阻塞渲染。
- 用
media="print"加载打印样式,完全不影响页面首屏 - 用
media="screen and (min-width: 769px)"延迟大屏专属样式,小屏设备跳过解析 - 别写
media="all"(这是默认值),显式写出条件才能触发惰性行为 - 注意:Safari 对动态改
media值的支持不稳定,改完要手动触发matchMedia().matches判断
内联关键CSS时要注意什么?
内联不是把整个 main.css 塞进 ,而是提取首屏 DOM 实际用到的选择器(含伪类、媒体查询嵌套),生成最小可行集。工具如 critters 或 Penthouse 可自动提取,但需配合真实 viewport 和用户代理模拟。
- 内联内容超过 ~14KB 会触发 HTTP/2 流优先级重排,反而可能变慢
- 服务端渲染(SSR)场景下,内联 CSS 必须随 HTML 一起生成,不能靠客户端 JS 注入
- CDN 缓存 HTML 时,内联 CSS 会污染缓存粒度——如果样式常变,就得关掉 HTML 缓存或引入版本哈希
- 不要内联含
@import的 CSS,它会触发额外请求,破坏内联意义
最麻烦的其实是动态主题切换:预加载 + 内联 + media 切换三者混用时,容易出现样式闪动或重复加载。这时候得靠 CSSStyleSheet.replace() 手动管理 sheet 实例,而不是反复删增 标签。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











