unocss比tailwind快2.5–3.7倍,核心在于它跳过ast解析与全量文件扫描,仅对html/jsx中字面量类名做轻量字符串匹配和缓存查表,而tailwind jit必须递归扫描、ast解析、正则匹配三步全量执行。

UnoCSS 的扫描速度比 Tailwind CSS 快 2.5–3.7 倍,核心原因不是“更快地扫”,而是根本**不扫**——它跳过了 AST 解析和全量文件遍历环节,只在类名实际出现时做轻量字符串匹配。
为什么 Tailwind CSS 的扫描慢?
Tailwind CSS(JIT 模式)必须完成三步不可省略的开销:
- 递归扫描
content配置中所有路径下的文件(如./src/**/*.{html,ts,tsx}) - 对每个文件做完整 AST 解析(用 PostCSS + css-tree),提取所有疑似工具类的 token
- 对每个提取出的类名,再匹配数百条正则规则(如
/^p-(\d+)$/、/^text-(\w+)-(\d+)$/),判断是否合法并生成对应 CSS
这个过程在项目达到 500+ 文件、10k+ 行模板代码时,冷启动构建会明显卡顿;且每次 HMR 触发,只要文件内容变动,就得重跑整套流程。
UnoCSS 是怎么绕过扫描的?
UnoCSS 不依赖文件内容扫描,而是靠「运行时拦截 + 缓存命中」实现按需生成:
- 开发时,Vite / Webpack 插件监听 HTML/JSX/TSX 中的 class 属性值(例如
class="p-4 text-red-500") - 对每个类名直接调用
generateCSS(className),内部用预编译的规则匹配器查表(O(1) 时间复杂度) - 匹配成功则生成 CSS 并写入虚拟的
uno.css;失败则静默忽略,不报错也不阻塞 - 已生成的类名自动进内存缓存(
this.cache.set(className, css)),后续重复使用不重新计算
这意味着:你删掉一个组件文件,UnoCSS 完全无感;新增一个从未用过的类名,它只多花几微秒匹配一次——没有“全量 re-scan”这回事。
加了 @apply 或 theme() 后,UnoCSS 还快吗?
会变慢,但依然快于 Tailwind。关键看你怎么用:
- 默认情况下,UnoCSS **不解析 CSS 文件里的
@apply、@screen或theme()** —— 它只处理 HTML/JSX 中的 class 字符串 - 若需支持这些语法,必须显式安装
@unocss/transformer-directives并注册到uno.config.ts - 此时 UnoCSS 确实会引入
css-tree解析 CSS AST,但仅限你明确 import 的 CSS 文件(比如index.css),不会像 Tailwind 那样扫描整个项目所有 CSS/SCSS - 实测数据:加入等量
@apply后,UnoCSS 构建耗时仍为328.39 ms,Tailwind 为798.42 ms(2024 年基准测试)
真正容易被忽略的点是:很多人以为“启用 transformer-directives 就等于完全复刻 Tailwind 工作流”,其实不是——UnoCSS 的 CSS 解析是 opt-in、文件粒度、非递归的,而 Tailwind 的扫描是强制、全量、递归的。这个设计差异,在 10 万行代码的 monorepo 里会直接决定你等不等得及喝完一杯咖啡。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











