应使用 chrome coverage 面板验证 css 使用率,低于90%即存在大量未用规则;重点关注:hover/:focus/@keyframes、重复图标类、深层嵌套选择器及:extend()是否真正生效,并排查递归mixin、ast爆炸、通配符import、压缩参数配置及tree shaking缺失问题。

检查编译后 CSS 是否存在大量未使用规则
别靠猜测,直接用 Chrome DevTools 的 Coverage 面板验证:打开「More Tools → Coverage」,刷新页面,看主 CSS 文件的使用率。低于 90% 就说明有大量白下、白析、白构的样式。
重点关注三类高危内容:
-
:hover、:focus、@keyframes等交互/动画规则,常因被@import (reference)文件意外引入而重复输出 - 同一套图标类(如
.icon、.btn-icon、.menu-icon)是否以逗号合并形式出现(.icon, .btn-icon, .menu-icon { })——这是:extend()成功的标志;若各自孤立成块,说明继承链已断 - 是否存在大量
.a .b .c .d { }这类深层嵌套选择器,它们不仅体积大,gzip 压缩率也低
确认 :extend() 是否真正生效
:extend() 不是开关,它只在「被继承的选择器真实存在于最终 CSS 中」时才合并选择器;否则退化为整段声明复制,体积反而更大。
常见失效场景:
- 目标类(如
.btn)来自@import (reference) "base.less"—— 它不输出 CSS,:extend()就无处可继 - 多个文件各自
@import "base.less"却没加(once),导致.btn被输出多份,各文件再分别:extend(),结果生成 N 套几乎一样的规则 - 写了
.btn-primary:extend(.btn)却漏了all关键字,无法继承.btn:hover等嵌套状态 - 路径不一致:
@import (once) "./_extends"和@import (once) "../base/_extends"被视为两个文件,(once)失效
排查递归 mixin 和深层嵌套引发的 AST 爆炸
Less 编译 OOM 或产物异常庞大,往往不是文件“大”,而是 AST 节点数指数级增长所致。20 层嵌套或无终止条件的递归 mixin 可轻松催生百万级节点。
快速定位方法:
- 临时注释掉所有
.mixin() { },仅保留静态样式;若仍 OOM,问题大概率出在嵌套层级或@import链上 - 运行
npx lessc --version,若输出lessc 3.9.0等旧版本,基本锁定是已知递归缺陷(3.9.x–3.10.2) - 检查是否有
.gen(@n) when (@n > 0) { .gen((@n - 1)); }这类写法——它在@n > 20时极易崩溃,应改为尾调用形式:.gen(@n) { .loop(@i) when (@i > 0) { .loop((@i - 1)); } .loop(@n); } - 禁用
@import "components/*.less":标准 Less 不支持通配符,构建工具静默加载全部文件,彻底废掉按需控制
验证压缩参数是否真起作用
--compress 只删空格换行,对体积影响微乎其微;真正有效的是 --clean-css,但它必须配对使用关键参数,否则可能适得其反。
必须检查的配置项:
- 是否安装了插件:
npm install -g less-plugin-clean-css - 命令中是否含
--advanced:缺它就不会合并选择器,--s1保留关键分号防 IE8 解析失败,--compatibility '*'防止rgba()被转 hex 后丢透明度 - 输入文件是否含大量
//行注释——clean-css默认保留它们,导致体积虚高 - 是否误启
--source-map或--sourcemap:sourcemap 会附在 CSS 底部,单文件涨几十 KB;CI/CD 中务必加--remove-source-maps
最易被忽略的一点:Less 本身不 Tree Shaking,所谓“按需”全靠你手动拆分入口、用 @import (reference) 隔离逻辑、并在构建工具中切断未引用路径。编译器不会替你判断哪段样式该消失。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











