
# 性能与测试

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

## 性能

PHP 移植版本优先匹配 TailwindCSS 的输出，而非追求原始吞吐量；无论如何，原版 TypeScript 都更快——V8 的 JIT 会将热点路径编译为原生代码，这是 PHP 无法比拟的。对于每个请求或每个页面生成的 CSS，请复用同一个编译器（参见 [generateExact()](https://tailwindphp.inline0.dev/zh/docs/api#accumulating-vs-exact-generation)），并使用 [`stateCacheFile`](https://tailwindphp.inline0.dev/zh/docs/advanced/caching#compiler-state-cache) 持久化其构造状态。

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

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

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

### 基准测试

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

```bash
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）。对于重复的相同输入，[文件缓存](https://tailwindphp.inline0.dev/zh/docs/advanced/caching) 可以彻底消除开销。

## 测试与一致性

测试用于确保 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 失败。

```bash
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 脚本运行：

```bash
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`），并忽略少量模式，以适应基于函数的架构所使用的动态数组形态。所有源文件都会接受分析；测试文件除外。

关于这些测试验证的结构以及偏差记录位置，请参见 [架构](https://tailwindphp.inline0.dev/zh/docs/advanced/architecture)。
