PurgeCSS 配合 HTML 语义化重构最有效,单纯删 CSS 不解决根本问题;真正降低冗余率需让 HTML 结构本身“说清楚它要什么样式”,因 PurgeCSS 默认只扫描 class 和 id 属性,无语义命名如 "box1" 或 "txt-red" 使其无法判断类是否真被业务依赖——只能看到“用了”,却不知“为何用”或“能否替换”。

purgecss 配合 HTML 语义化重构最有效
单纯删 CSS 不解决根本问题;真正降低冗余率,得让 HTML 结构本身“说清楚它要什么样式”。purgecss 默认只扫描 class 和 id 属性,如果 HTML 里满是 <div class="box1">、<span class="txt-red"> 这类无语义命名,工具就无法判断哪些类是否真被业务逻辑依赖——它只能看到“用了”,但不知道“为什么用”或“还能不能换”。
实操建议:
- 先用
purgecss跑一遍,导出未使用选择器列表(启用rejected选项),把高频出现但实际已废弃的类名记下来 - 对照这些类名,反查 HTML 模板:是某个旧功能残留?还是某次 A/B 测试留下的临时 class?直接删对应 DOM 节点或改用语义化标签替代(比如把
<div class="btn-primary">换成<button type="submit">) - 重构时优先用原生语义标签承载行为意图(
<nav>、<article>、<dialog>),再通过属性选择器写样式(如button[type="submit"]),减少对 class 的强依赖
uncss 在 SPA 中容易漏掉动态插入的 class
uncss 基于 PhantomJS 或 Puppeteer 加载页面并执行 JS,但它默认只抓取首屏静态 HTML 中的 class,对运行时通过 el.classList.add("is-open")、React.createElement 动态挂载的类名基本无感知——这类 class 会直接被判定为“未使用”而误删。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
- 下拉菜单展开后样式丢失
- 模态框打开时背景遮罩无颜色
- Vue
v-if切换后元素样式不生效
解决方法:
- 在
uncss的ignore选项里显式保留动态类前缀,例如:ignore: [/^is-/, /^has-/, /^js-/] - 避免用纯 JS 控制 class 切换,改用
data-*属性 + 属性选择器(如[data-state="open"] > .panel),uncss能识别data-属性但不分析其值变化 - 对关键交互路径,单独起一个含完整状态的 HTML 快照文件(如
modal-full.html),加入uncss的files数组中一并扫描
Webpack 插件 purifycss-webpack 已弃用,别再配置了
purifycss-webpack 从 2020 年起就不再维护,它依赖已停更的 purify-css 库,与 Webpack 5+ 的模块图 API 不兼容。实际打包时看似能跑通,但会跳过 CSS Modules、@import 嵌套、以及所有通过 style 标签注入的 runtime CSS —— 最终删掉的只是冰山一角,还可能破坏 source map 映射。
正确迁移路径:
- 立即卸载:
npm uninstall purifycss-webpack purify-css - 改用官方推荐的
postcss-purgecss,配合 PostCSS 插件链,在 CSS 构建末期介入,支持content字段精准指定 HTML/JS 模板路径 - 若项目用 Vite,直接启用内置的
build.cssCodeSplit+build.rollupOptions.plugins注入@fullhuman/postcss-purgecss,无需额外处理 extract-text - 注意:PurgeCSS 的
keyframes和font-face默认不保留,必须手动加进whitelistPatterns,否则动画和自定义字体失效
Chrome Coverage 只能看“加载时”使用情况
DevTools 的 Coverage 面板显示的是当前页面加载完成那一刻的 CSS 规则命中状态,它不会跟踪后续用户操作触发的样式变化。比如一个 :hover 规则、@media (prefers-reduced-motion) 媒体查询、甚至 prefers-color-scheme: dark 下的暗色模式样式,只要没在初始渲染中激活,就会被标红为“未使用”。
这导致两个典型误判:
- 把完整的响应式断点 CSS 当成冗余删掉,结果在平板横屏下布局崩塌
- 删除所有伪类相关规则,导致按钮悬停、焦点轮廓全部消失,可访问性严重受损
安全做法:
- Coverage 仅作初筛,重点标记出“从未出现在任何
class/id中”的规则(即连选择器都没被写进 HTML) - 对带伪类、媒体查询、属性选择器的规则,一律保留,除非你确认该交互路径已被下线
- 用 Lighthouse 的
Accessibility报告交叉验证:如果 Coverage 显示某段 CSS 未用,但 Lighthouse 提示 “Focusable element has no focus style”,说明它其实有用,只是没在初始帧触发
真正难清理的不是“明显死代码”,而是那些和业务逻辑耦合太深的 class —— 它们在 DOM 里有调用痕迹,但语义早已漂移,或者只服务于某个已下线的 AB 实验。这类代码必须结合 Git 历史 + 产品文档 + 线上埋点数据才能安全下线,工具只能帮你划出范围,没法替你做判断。



















