HTML关键CSS提取速查方法

作者:技术拾光时间:2026-06-29 08:25:00浏览:566

关键 CSS(Critical CSS)并非简单地将所有 CSS 代码“拆出来”,而是仅提取首屏渲染时实际用到的样式规则。媒体查询、伪类、@import、非首屏组件等“冗余”内容,均应跳过。直接依赖正则匹配或一股脑全量注入,极易出现问题——真正可落地的方案,需依据所使用的运行环境而定。 使用 cri

关键 CSS(Critical CSS)并非简单地将所有 CSS 代码“拆出来”,而是仅提取首屏渲染时实际用到的样式规则。媒体查询、伪类、@import、非首屏组件等“冗余”内容,均应跳过。直接依赖正则匹配或一股脑全量注入,极易出现问题——真正可落地的方案,需依据所使用的运行环境而定。

HTML关键CSS提取速查方法

使用 critters 在构建时提取(适用于 Vite / Webpack 场景)

critters 是目前最稳定的 Node.js 端提取器。其工作方式并非纯字符串解析,而是基于真实 DOM 渲染快照结合 CSSOM 分析。它能自动忽略 @media (min-width: 768px)、:hover 以及那些不在首屏 DOM 中的选择器(例如 .sidebar)。

  • Webpack 用户:配置 CrittersPlugin,传入 html 入口路径和 publicPath,插件会自动将 注入到 中。
  • Vite 用户:使用 vite-plugin-critters,需注意必须开启 build.ssr 或预渲染 HTML,否则无法获取 DOM 快照进行分析。
  • 注意事项:critters 不会处理内联 中的 @import。如果 CSS 中使用了 @import 'base.css',它不会加载并解析该文件。

使用 penthouse 在服务端提取(适用于 Node.js 运行时)

penthouse 本质上会启动一个无头浏览器(Puppeteer),打开页面、截取首屏 DOM,然后反向推导出哪些 CSS 规则被实际使用。它比 critters 更精确,但代价是速度慢、内存占用高。适合在 CI/CD 阶段运行一次生成,不适合在请求时动态执行。

  • 必须提供一个可访问的 URL(例如 http://localhost:3000/home),不能仅提供 HTML 字符串。
  • 默认超时为 30 秒,对于复杂的 SPA,建议设置为 timeout: 60000,否则可能因 JS 加载未完成而遗漏某些规则。
  • 输出是纯 CSS 字符串,不带 标签,需要自行拼入 HTML —— 别忘了加上 type="text/css"。

使用 cheerio + 手动规则过滤(适用于纯 HTML 字符串场景)

如果只有静态 HTML 字符串(例如 CMS 输出、邮件模板),没有服务端渲染能力,又不想引入 Puppeteer,则只能退回到“启发式提取”:先用 cheerio 解析 DOM,再按规则筛选 和 ,最后依靠白名单控制范围。

  • 仅加载 href 路径中包含 /css/critical. 的样式表;media="print" 的样式表直接排除(不属于关键样式)。
  • 跳过所有包含 @media、@supports、:not(、::before 的规则行——使用 postcss 解析 AST 会更稳定,但也会更重。
  • cheerio.load(html).$('link[rel="stylesheet"][href*="critical"]').attr('href') 仅获取链接,不会下载内容——下载操作需自行用 fetch 或 axios 补充。

为什么不建议用正则从 HTML 字符串中直接抽取 CSS 内容?

因为 和 都位于 标签内,但后者大概率不属于关键 CSS。正则无法区分语义,只能按标签边界切割,结果要么过于粗放(全部提取),要么过于细碎(遗漏复合选择器)。更麻烦的是,CSS 中可以包含换行、注释、Unicode 转义,正则极易失效——即使写对了,下次设计师添加一个 /* mobile-first */ 注释也可能导致整个提取失败。