关键CSS是首屏渲染必需的最小样式集合,提取易错因误含非首屏规则、未剔除@media分支、JS动态类干扰及url()仍阻塞;体积应≤4KB,否则TTFB和解析耗时反超收益。

因为浏览器必须等 CSSOM 构建完成才能开始首屏渲染,而外部 CSS 文件会阻塞 HTML 解析;内联关键 CSS 能让首屏样式随 HTML 一起到达,直接打破白屏,但前提是只内联真正首屏用到的规则——多一条都可能拖慢解析。
什么是关键CSS,提取时为什么容易错
关键 CSS 不是“首页用到的所有 CSS”,而是仅覆盖当前 viewport 内可见内容所需的最小样式集合。常见误判包括:
- 把
.card、.modal这类首屏根本没出现的选择器也塞进去 - 保留了
@media (min-width: 1200px)分支,但测试设备宽度是 375px - 提取时没禁用 JavaScript,导致
.is-loaded这类 JS 动态添加的 class 对应规则被误纳入 - 漏掉
background: url(//cdn.example.com/logo.png)这类仍会触发网络请求的声明,实际仍阻塞渲染
内联后 HTML 变大,反而更慢?怎么控制体积
内联不是为了“省一次请求”,而是为了抢在白屏窗口期完成 CSSOM。但体积失控会反噬性能:
-
critical工具默认提取结果常达 8–15KB,移动端弱网下 TTFB 后的 HTML 解析时间可能超过节省的 CSS 下载时间 - 建议硬性限制内联体积 ≤ 4KB(Chrome DevTools → Network → Disable cache + Offline 模式验证)
- 构建时用
critters(Webpack)或next-critical-css(Next.js)自动压缩、去重、剔除 @import 和 url() 引用 - SSR 场景下必须确保服务端生成的 DOM 结构与真实首屏一致,否则提取结果为空或错位
非关键 CSS 怎么加载才不阻塞渲染
内联完关键部分后,剩余 CSS 必须异步加载,否则仍会阻塞:
立即学习“前端免费学习笔记(深入)”;
- 不能用
<link rel="stylesheet">,它默认同步阻塞 - 推荐用
<link rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">,配合<noscript><link rel="stylesheet" href="non-critical.css"></noscript> - CSR(如纯 React SPA)基本不适合做 critical CSS 提取——首屏 DOM 是空的,工具提取不到有效规则
- 如果用了
grunt-critical,注意它默认会把非关键 CSS 包进 JS 函数里异步注入,需确认是否兼容你的 JS 加载逻辑
真正难的不是“怎么内联”,而是判断哪些规则在特定视口、禁用 JS、无缓存条件下确实参与了首屏渲染——这个边界模糊,靠工具辅助也得人工交叉验证。



















