跳转到正文

性能与测试

TailwindPHP 优先保证正确性。若特定于 PHP 的改动能在不改变输出的前提下提升速度,就会采用并标记为 @port-deviation:performance。不会假定与 TailwindCSS 保持一致,而是持续使用 Tailwind 自带的测试套件进行验证。

性能

PHP 移植版本优先匹配 TailwindCSS 的输出,而非追求原始吞吐量;无论如何,原版 TypeScript 都更快——V8 的 JIT 会将热点路径编译为原生代码,这是 PHP 无法比拟的。对于每个请求或每个页面生成的 CSS,请复用同一个编译器(参见 generateExact()),并使用 stateCacheFile 持久化其构造状态。

少数热点路径采用了手工调优的优化,同时确保输出完全相同:

  • ast.php toCss() — 在数组中累积片段,并一次性调用 implode,而不是反复拼接字符串,同时使用预先计算的缩进字符串。
  • css-parser.php — 直接比较字符,而不是通过 ord(),并跟踪缓冲区长度,而不是重复计算 strlen()。

两项优化都有 @port-deviation:performance 文档,并受测试套件约束——它们无法改变生成的 CSS。

基准测试

benchmarks/ 目录中包含一个对比测试工具。运行命令如下:

命令行
composer bench         # PHP vs TypeScript
composer bench:save    # write benchmarks/results.json

PHP 8.4.5 / Node.js v22.17.0(Apple M1)上的示例结果:

基准测试 PHP TypeScript
css-parser(在 preflight.css 上) ~816 ops/s ~15.45K ops/s(约快 20 倍)
toCss ~65.85K ops/s ~2.59M ops/s(约快 39 倍)

对于这些底层操作,TypeScript 更快,这符合预期。对于完整页面的 CSS 生成——实际使用场景——PHP 的性能足够好(示例运行中每页约 14 ms)。对于重复的相同输入,文件缓存 可以彻底消除开销。

测试与一致性

测试用于确保 PHP 移植版本生成的输出与 TailwindCSS 相同。两种方法相互配合。

1. 基于提取的测试。 test-coverage/ 中的脚本会解析 TailwindCSS 自带的 .test.ts 文件,并将测试用例提取到 JSON。随后,PHPUnit 会将这些用例交给 TailwindPHP 运行,并将输出与预期的 CSS 进行比较。由于预期结果直接来自上游,PHP 行为的任何偏差都会导致失败。这些测试覆盖复杂部分:工具、变体、集成、CSS 函数以及浏览器级别的 ui.spec 测试。

2. 手动移植的单元测试。 较简单的 TypeScript 测试文件(AST、CSS 解析、转义、候选项解析、值解析等)会直接移植到 PHP,作为 *.test.php 放在相应源码旁边,其结构和断言与原版保持一致。

循环流程是提取 → 运行 → 验证:从当前的 TailwindCSS 参考版本重新提取,运行测试套件,任何偏差都会导致失败。这样可使移植版本与上游保持同步,并能通过机械化方式验证 TailwindCSS 更新,而不必人工检查。偏差会导致 CI 失败。

命令行
composer extract   # re-extract test cases from the TailwindCSS reference
composer test      # run the full suite

截至发布版本 1.7.0(TailwindCSS v4.3.3 参考版本),共有 4,427 项测试通过:

套件 测试数 来源
提取的 TailwindCSS 套件(工具 706、变体 164、索引 148、css-functions 64、ui.spec 68) 1,150 从 .test.ts / .spec.ts 提取
API 覆盖(工具、修饰符、变体、指令、插件、导入、@source、缓存、公共 API) 2,252 tests/
源码旁的单元测试(解析器、AST、候选项、主题、工具、选择器解析器、lightningcss 变换、压缩器) 767 *.test.php 移植版本和特定于 PHP 的测试
CLI(参数解析、输出、构建) 84 tests/Cli*Test.php
插件移植版本(typography、forms) 45 与插件并列的 *.test.php
配套库(clsx、tailwind-merge、CVA) 129 参考套件

代码质量

格式化和静态分析通过 Composer 脚本运行:

命令行
composer lint      # Pint --test  (check formatting)
composer format    # Pint         (fix formatting)
composer analyse   # PHPStan      (static analysis, level 4)
composer quality   # lint + analyse

PHPStan 以第 4 级运行(phpstan.neon),并忽略少量模式,以适应基于函数的架构所使用的动态数组形态。所有源文件都会接受分析;测试文件除外。

关于这些测试验证的结构以及偏差记录位置,请参见 架构。