不能只靠正则提取关键CSS,因其无法处理动态渲染DOM、伪类交互态、响应式断点及@import规则;critters基于本地HTML文件用Puppeteer分析首屏DOM并注入<style>,penthouse需HTTP URL且返回纯CSS字符串,更适合SPA和CI验证。

为什么不能只靠正则提取关键 CSS
正则匹配 <link rel="stylesheet"> 或提取 @media 规则行,看似快,但会漏掉动态渲染内容(比如 React/Vue 组件挂载后才出现的 DOM)、伪类交互态(:hover、:focus-within)、响应式断点(@media (min-width: 768px) 在横屏平板首屏就生效),甚至把 @import 当普通规则跳过。工具链必须基于真实 DOM 快照,而不是 HTML 字符串静态分析。
critters 和 penthouse 的核心差异在哪
两者都依赖 Puppeteer 模拟浏览器,但运行时机和输入来源不同:
-
critters接收已构建的 HTML 文件路径(如dist/index.html)和对应 CSS 资源路径,启动无头浏览器访问本地文件(file://协议),解析首屏 DOM 后反向映射 CSS 规则;它不处理内联<style>中的@import,也不支持远程 URL -
penthouse必须传入可访问的 HTTP URL(如http://localhost:3000),适合开发服务器已启动的场景;它能等 JS 执行完成再截图,对 SPA 更友好,但默认超时 30s,复杂页面需手动设timeout: 60000 - 输出也不同:
critters直接注入<style>标签到 HTML;penthouse只返回纯 CSS 字符串,你得自己拼<style type="text/css">...</style>
Vite 和 Webpack 用户怎么配才不踩坑
Vite 用户优先用 vite-plugin-critters,但注意它依赖预渲染能力——如果项目没开 build.ssr 或没用 prerender 插件,生成的 HTML 里没有首屏 DOM,critters 就无从分析,结果为空。Webpack 用户配 CrittersPlugin 时,确保 html-webpack-plugin 和 mini-css-extract-plugin 已启用,且 CSS 提取顺序在 critters 运行之前,否则插件找不到 CSS 文件路径。
CI/CD 阶段该选哪个工具
CI 环境里推荐 penthouse,不是因为它“更好”,而是它更可控:
立即学习“前端免费学习笔记(深入)”;
- 它强制走 HTTP 请求,能验证服务端实际响应(比如 SSR 是否生效、CDN 缓存是否命中)
- 可指定 viewport 宽高(
width: 1920, height: 1080)、设备类型(emulateMobile: false),避免本地开发环境与线上渲染差异 - 失败时直接报错退出,不会静默生成残缺 CSS;而
critters在找不到 DOM 元素时可能只输出 body 基础样式
真正容易被忽略的是:所有工具都默认只分析首次加载的 DOM,如果首屏内容依赖用户滚动或懒加载触发,那些样式就得手动加白名单,或者换用运行时注入方案(比如 loadCSS + onload 回调补关键规则)。



















