缓存和压缩
流水线末端有三个生产环境相关事项:避免对相同输入重复编译,避免每次请求都承担构建编译器的开销,以及缩小生成的 CSS。这三者都是围绕编译器的 PHP 端辅助功能。
缓存
每次调用 CSS 都会运行完整流水线。对于请求之间内容不变的情况,基于文件的缓存会将结果写入磁盘,并在后续调用时直接提供。
将 cache 传给 tw::generate();true 表示默认目录,也可以传入自定义路径字符串:
use TailwindPHP\tw;
// Cache to the default directory: sys_get_temp_dir() . '/tailwindphp'
$css = tw::generate([
'content' => '<div class="flex p-4">Hello</div>',
'cache' => true,
]);
// Cache to a custom directory
$css = tw::generate([
'content' => '<div class="flex p-4">Hello</div>',
'cache' => '/path/to/cache',
]);
// With a time-to-live (seconds)
$css = tw::generate([
'content' => '<div class="flex p-4">Hello</div>',
'cache' => true,
'cacheTtl' => 3600, // expire after 1 hour
]);
如果缓存目录不存在,系统会自动创建。
缓存键
缓存键由 内容、CSS 配置和 minify 标志生成,并用作文件名 tailwind_<hash>.css。标记内容、CSS 输入或是否启用压缩的任何变化,都会生成不同的键,因此对应不同的文件。
键中的 CSS 配置包含内联的 css 以及 importPaths 中列出文件的内容。两种输入不包含在内:这些文件通过嵌套的 @import 引入的文件,以及 TailwindPHP 版本。编辑嵌套导入文件或升级软件包后,请清除缓存,否则系统会继续提供旧输出。
生存时间
cacheTtl 的单位是秒,表示有效时长。命中缓存时,系统会将文件修改时间与当前时间比较;如果文件的时间早于 cacheTtl,则视为未命中并重新编译。若未设置 cacheTtl,缓存条目永不过期,需要手动清除。
清除缓存
tw::clearCache()(或 clearCache() 函数)会从缓存目录中删除 tailwind_*.css 文件,并返回已删除文件的数量。
use TailwindPHP\tw;
use function TailwindPHP\clearCache;
$deleted = tw::clearCache(); // default directory
$deleted = tw::clearCache('/path/to/cache'); // custom directory
clearCache('/path/to/cache'); // function form
编译器状态缓存
只有相同内容再次出现时,输出缓存才有用。如果每次调用时内容都发生变化,开销较大的是构建编译器本身:解析 @import "tailwindcss"、解析打包资源并累积主题。此阶段仅取决于输入 CSS,因此可以存储并重复使用。
将 stateCacheFile 传给 tw::compile()(或 new TailwindCompiler($css, $options)):
use TailwindPHP\tw;
$compiler = tw::compile($themeCss, [
'stateCacheFile' => __DIR__ . '/cache/tailwind-state.php',
]);
$css = $compiler->generateExact($html, true);
首次构建时,状态会以纯 PHP 文件写入该路径,OPcache 可在请求间共享此文件;后续构建会直接加载该文件,不再重新解析。输出与未使用缓存的编译器逐字节一致。
- 系统会根据引擎指纹(TailwindPHP 源码和资源的大小及修改时间)、由输入 CSS、
base和importSearchPaths选项生成的键,以及输入导入的每个文件的大小和修改时间验证文件。如果不匹配,系统会重新构建并写入文件,因此升级 TailwindPHP 或编辑导入文件时无需手动操作。 - 路径由你负责:针对每种不同的输入 CSS 使用单独文件,并将其放在 Web 服务器可写入的目录中。写入是原子操作(先写入临时文件,再执行
rename())。 - 使用自定义
importResolver的输入会绕过缓存,因为无法为解析器的行为生成指纹。 - 较低层级的
compile()数组 API 也可使用同一缓存,方式为TailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options)。
tw::generate() 不接受 stateCacheFile;每次调用都会构建新的编译器。若需控制构建开销,请使用编译器实例。
压缩
压缩可以缩小生产环境中的输出。minify 标志会在序列化期间直接生成压缩后的 CSS,因此速度最快、精度也最高;tw::minify() 会对现有的 CSS 字符串运行基于字符串的压缩器(src/_tailwindphp/CssMinifier.php):
use TailwindPHP\tw;
// Minify during generation (serializer path, preferred)
$css = tw::generate([
'content' => '<div class="flex p-4">Hello</div>',
'minify' => true,
]);
// Or minify an existing string (string-based post-pass)
$css = tw::generate('<div class="flex p-4">Hello</div>');
$minified = tw::minify($css);
两种路径生成的结构等效,但字节并不完全相同。序列化器路径会保留后代 :not() 选择器,而字符串处理流程会将其折叠,因此生成输出时优先使用 minify 标志;如果 CSS 是以字符串形式传入的,则使用 tw::minify()。
功能说明
两种路径都会应用相同的一组缩减操作:
| 步骤 | 效果 |
|---|---|
| 移除注释 | 移除 /* … */ 块 |
| 合并空白 | 合并连续空白,并移除 { } ; : , 周围及选择器组合符周围的空白 |
| 缩短十六进制颜色 | #ffffff → #fff,#aabbcc → #abc |
| 移除零单位 | 0px → 0(保留 0s/0ms 时间值) |
| 缩短字重 | font-weight:normal → 400,font-weight:bold → 700 |
| 移除空规则 | 删除声明块为空的选择器 |
按照设计,压缩器不会合并重复选择器或组合简写属性,因为这两种操作都会增加调试难度,并可能影响层叠效果。
CLI:--minify 与 --optimize
CLI 通过两个标志开放了序列化器的压缩路径:
# Optimize and minify (smallest output)
tailwindphp -i ./src/app.css -o ./dist/styles.css --minify # or -m
# Meant to optimize without minifying
tailwindphp -i ./src/app.css -o ./dist/styles.css --optimize
在当前版本中,--optimize 也会进行压缩,因此两个命令写入的字节相同(#9)。无论采用哪种方式,每次构建都会运行与 lightningcss 等效的转换,因此不带标志的普通输出已经经过优化且易于阅读。
有关其余公开 API(tw::generate()、tw::compile()、检查方法和输入格式),请参阅 API 参考。