
# パフォーマンスとテスト

TailwindPHPはまず正確性を重視して最適化されています。PHP固有の変更で出力を変えずに高速化できる場合は適用し、`@port-deviation:performance`とマークします。TailwindCSSとの同等性は前提とせず、Tailwind独自のテストスイートに対して継続的に検証しています。

## パフォーマンス

PHPポートは処理速度よりもTailwindCSSの出力との一致を優先します。また、TypeScriptのオリジナルのほうが常に高速です。V8のJITはホットパスをネイティブコードにコンパイルしますが、PHPでは同じことができません。リクエストごと、またはページごとにCSSを生成する場合は、コンパイラーを1つ再利用し（[generateExact()](https://tailwindphp.inline0.dev/ja/docs/api#accumulating-vs-exact-generation)を参照）、その構築状態を永続化してください（[`stateCacheFile`](https://tailwindphp.inline0.dev/ja/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× faster) |
| `toCss` | ~65.85K ops/s | ~2.59M ops/s (≈39× faster) |

こうした低レベルの処理では、予想どおりTypeScriptのほうが高速です。実際の用途であるページ全体のCSS生成では、PHPのパフォーマンスは十分です（サンプル実行で1ページあたり約14 ms）。同じ入力を繰り返し使う場合は、[ファイルキャッシュ](https://tailwindphp.inline0.dev/ja/docs/advanced/caching)によって処理コストを完全になくせます。

## テストと同等性

PHPポートがTailwindCSSと同じ出力を生成することを保証するテストがあります。2つの方法を組み合わせて使います。

**1. 抽出ベースのテスト。** `test-coverage/`内のスクリプトがTailwindCSS独自の`.test.ts`ファイルを解析し、テストケースを抽出してJSONに格納します。次にPHPUnitが各ケースをTailwindPHPに渡し、出力を期待されるCSSと比較します。期待値は上流から直接取得するため、PHPの動作に少しでも差異があれば失敗として検出されます。ユーティリティ、バリアント、統合、CSS関数、ブラウザレベルの`ui.spec`テストなど、複雑な領域を網羅します。

**2. 手動移植した単体テスト。** AST、CSS解析、エスケープ処理、候補の解析、値の解析など、比較的単純なTypeScriptテストファイルを直接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時点で**4,427件のテストに合格**しています（TailwindCSS v4.3.3リファレンス）:

| テストスイート | テスト数 | 出典 |
|-------|-------|--------|
| 抽出した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/ja/docs/advanced/architecture)を参照してください。
