critical命令行工具提取不准的根本原因是其依赖已启动服务且需等待js渲染完成,而本地开发环境常未暴露稳定url或过早抓取dom;必须配合--timeout、--wait-for等参数确保首屏内容渲染完毕,并显式访问spa路由路径,同时入口css须提前合并所有关键规则。

critical 命令行工具在本地开发中为什么总提取不准
根本原因是它依赖一个已启动的服务地址,而多数本地开发环境(如 Vite 的 vite dev)默认不暴露稳定 URL 或未等 JS 渲染完成就抓取 DOM。你看到的“关键 CSS 为空”或“只提取了 body 默认样式”,大概率是 critical 请求时页面还是空白或未挂载 Vue/React 组件。
实操建议:
- 必须确保服务已启动且首屏内容已渲染完成——加
--timeout 60000并配合自定义等待逻辑,例如--wait-for ".hero-banner"等待关键元素出现 - SPA 路由页需显式访问对应路径,比如
critical http://localhost:5173/product --target product-critical.html,不能只跑根路径 - 若用
generate()API,务必传ignoreConsole: false并监听window.__INITIALIZED__ = true这类标记,否则 JS 异步渲染的内容全被跳过 -
@import规则完全不处理,所有关键规则必须提前合并进入口 CSS 文件,否则提取结果漏掉基础重置样式
Vite 项目里用 critters 插件却没生成内联 style
这不是插件没装好,而是 critters 根本没拿到有效 DOM 快照——Vite 默认构建不预渲染 HTML,critters() 插件看到的是空 ,自然无法追踪样式依赖。
必须满足两个前提才能生效:
- 开启 SSR 或预渲染:设
build.ssr: true,或使用vite-plugin-prerender并配置prerenderRoutes: ['/']确保首屏路由被静态生成 - 首屏结构必须与 JS 执行前一致:如果靠
router.push或onMounted动态插入关键节点,critters 就看不到它们;得把首屏 DOM 提前写死在模板里,或在 prerender 阶段模拟挂载 - 推荐直接用
vite-plugin-critters,它会接管 HTML 构建流程,自动移除原始<link rel="stylesheet">,比手动加critters()更可靠
内联 critical CSS 后反而出现 FOUC 或样式错乱
常见于三类硬伤:体积超限、规则缺失、加载顺序错位。浏览器解析 HTML 是流式的,<style data-critters></style> 如果放在 <link> 后面,或者含非法声明,就会让优化变成负优化。
避坑要点:
- gzip 后体积严格控制在
14KB内——用gzip -c critical.css | wc -c验证,超了优先砍掉高权重低使用率的选择器(如.page section:nth-child(5) .card:hover) - 绝对禁止出现在内联块里的东西:
@import、background-image: url(...)、@font-face;字体改用<link rel="preload" as="font">+font-display: swap -
<style></style>必须置于最顶部,且紧挨着<meta charset>后;任何<link rel="stylesheet">都得挪到它后面,否则仍阻塞渲染 - 媒体查询要按设备单独提取:移动端用
--width 375 --height 667,桌面端另跑一次,混用会导致横屏平板漏掉导航栏关键样式
Webpack 中 CrittersPlugin 和 critical 工具的核心差异
两者都提取关键 CSS,但触发时机和能力边界完全不同:CrittersPlugin 是构建时读取打包后的 HTML 字符串,critical 是运行时请求真实页面快照。选错就容易漏提或提错。
关键区别:
- CrittersPlugin 不依赖服务,但“看不见 JS 渲染后的内容”——如果你的首屏靠 React.lazy 动态加载,它只分析 HTML 模板静态部分,
.product-list样式大概率被忽略 - critical 必须启动服务,但能等 JS 就绪,适合 CI/CD 阶段做精准快照;加
--user-agent "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)"可模拟移动端 UA - 两者都不处理
@import,也不解析<style></style>标签内的规则——所有关键 CSS 必须来自外部.css文件,且入口文件要包含全部依赖 - 输出都是纯 CSS 字符串,注入 HTML 时务必手动加上
type="text/css",否则旧版 Safari 会忽略该<style></style>
vite-plugin-prerender 没访问到正确路由,或 critical 的 --wait-for selector 写错了,提取结果就只是个安慰剂。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











