关键CSS是首屏渲染必需的样式规则,非全量内联style.css;全量内联会增大HTML体积,拖慢首字节传输与解析,尤其弱网下延迟显著。

什么是关键CSS,为什么不能全量内联
关键CSS是首屏渲染必须用到的那部分样式规则,不是整个 style.css。全量内联会增大HTML体积,反而拖慢首次字节传输和解析——尤其在弱网下,index.html 变大100KB,可能多等300ms才开始解析样式。
- 只提取视口内组件(如导航、标题、首张卡片)用到的选择器,不含折叠区域、懒加载模块、媒体查询中非当前断点的规则
- 工具链里
critters比Penthouse更轻量、更适配现代构建(如Vite),且默认跳过@import和外部字体请求 - 注意:CSS-in-JS(如Emotion)需额外配置服务端渲染时的 critical CSS 提取入口,否则提取结果为空
如何用critters自动提取并注入关键CSS
critters 是目前最省心的关键CSS处理方案,它直接操作HTML AST,在构建阶段把关键样式内联进 ,同时把剩余CSS转成异步加载的 <link rel="preload">。
- 在Vite中安装:
npm install critters --save-dev,然后在vite.config.ts的build.rollupOptions.plugins中加入critters() - 默认只处理
<link rel="stylesheet">,不处理<style></style>标签或style属性;若项目有动态插入的样式表,得手动标记data-critters="skip"避免误处理 - 输出HTML中会出现类似这样的结构:
<style data-critters>h1{font-size:24px}...</style><link rel="preload" as="style" href="/assets/style.abc123.css" onload="this.onload=null;this.rel='stylesheet'">,注意onload回调里清空了自身,防止重复执行
手动提取关键CSS时容易漏掉的三类选择器
自动化工具会漏判,尤其当样式依赖运行时状态。手动提取时最容易忽略的是:
- 伪类样式:比如
.btn:hover、.menu[open]—— 即使首屏没触发,浏览器仍需提前知道这些规则才能快速响应交互,建议保留 - 继承链中的上级规则:例如首屏有
<p class="content"></p>,但.content p或article p定义在别处,提取器若没模拟DOM树就可能丢掉 - 字体加载前的 fallback 样式:如果用了
@font-face,且首屏文字依赖该字体,要确保font-display: swap+ 对应的font-familyfallback 声明在关键CSS里,否则会闪动
内联后如何验证是否真起效
别只看HTML里有没有 <style data-critters></style>,重点看实际渲染行为:
立即学习“前端免费学习笔记(深入)”;
- 用Chrome DevTools打开
Network → Disable cache,刷新页面,观察Waterfall中index.html下方是否立刻出现render-blocking样式(没有则说明关键CSS已覆盖) - 在
Lighthouse → Performance报告中检查Critical Request Chains,确认首屏资源链路里没有阻塞的CSS请求 - 如果用了
rel="preload"加载非关键CSS,留意控制台是否有Failed to load resource: the server responded with a status of 404—— 这通常是因为构建后路径哈希变更,但critters没读取最新 manifest,需检查其manifestPath配置是否指向正确的manifest.json


















