Tailwind CSS v3的JIT模式构建更快,因其将“全量扫描+预生成”改为“按需扫描+实时生成”,仅解析content路径中静态出现的类名,省去I/O、正则匹配与字符串拼接开销;v2的AOT则硬编码输出约6000行工具类。

Tailwind CSS v3 的 JIT 模式不是“比旧版 CSS 有优势”,而是彻底改变了构建逻辑——它不生成冗余规则,只编译你代码里白纸黑字写出来的类名。
为什么 JIT 构建更快:省掉的是 I/O 和字符串匹配,不是 CSS 行数
旧版 v2 的 AOT 模式启动就硬编码输出约 6000 行工具类(text-xs 到 text-9xl、所有断点下的 flex 变体),哪怕你只用了 text-lg 和 md:flex;JIT 则只扫描 content 路径下文件,提取实际出现的类名字符串,再生成对应规则。真正耗时的是读文件、正则匹配、拼接字符串这三块,JIT 把它们全砍掉了。
- 构建时间从 v2 的 30–45 秒降到 v3.0+ 的 ~800ms(典型项目)
- 首次启动稍慢?正常——它在完整扫描 + 构建初始 AST,不是缺陷,是必要代价
- 热更新快,因为只重扫变更文件 + 增量合并 AST,不用重建整张样式表
content 配置写错 = JIT 失明
JIT 不认 purge 字段,只认 content 数组。路径漏配、类型写错、通配过宽,都会让它“看不见”你写的类,最终退化为全量生成(CSS 体积常超 2MB):
-
漏扩展名:React 项目写
["./src/**/*.{js,ts}"],漏了jsx和tsx,组件里的className全失效 -
通配过宽:写
["./**/*"],会扫node_modules和dist,I/O 拖垮构建,还可能误读压缩代码 -
正确写法:
["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"];Next.js 还要加"./app/**/*.{js,ts,jsx,tsx}"
@apply 和动态类名为什么容易失效
JIT 基于静态 AST 分析,对运行时行为无感知:
立即学习“前端免费学习笔记(深入)”;
-
@apply bg-blue-500 hover:bg-blue-600生效的前提,是bg-blue-500至少在某个模板中单独出现过;否则 JIT 不生成其底层规则 -
className={`p-${padding}`}或class="text-${size}"这类拼接,JIT 解析不到具体值,直接跳过,样式丢失 - 解决办法:
safelist显式声明可能组合(如['p-2', 'p-4']),或改用@apply封装,或用theme('spacing.4')内联值绕过类名解析
最常被忽略的一点:JIT 的“按需”不是按你“想用”,而是按你“已写死”的字符串。它不猜、不推、不运行 JS,只忠实提取源码里白纸黑字的类名——漏一个扩展名,就等于关掉一半眼睛;多扫一个无关目录,冷启时间可能翻倍。


















