パフォーマンスとテスト
TailwindPHPはまず正確性を重視して最適化されています。PHP固有の変更で出力を変えずに高速化できる場合は適用し、@port-deviation:performanceとマークします。TailwindCSSとの同等性は前提とせず、Tailwind独自のテストスイートに対して継続的に検証しています。
パフォーマンス
PHPポートは処理速度よりもTailwindCSSの出力との一致を優先します。また、TypeScriptのオリジナルのほうが常に高速です。V8のJITはホットパスをネイティブコードにコンパイルしますが、PHPでは同じことができません。リクエストごと、またはページごとにCSSを生成する場合は、コンパイラーを1つ再利用し(generateExact()を参照)、その構築状態を永続化してください(stateCacheFile)。
いくつかのホットパスには、出力を完全一致させる手動調整済みの最適化があります:
ast.phptoCss()— 文字列を繰り返し連結する代わりに、断片を配列に蓄積して一度だけ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× faster) |
toCss |
~65.85K ops/s | ~2.59M ops/s (≈39× faster) |
こうした低レベルの処理では、予想どおりTypeScriptのほうが高速です。実際の用途であるページ全体のCSS生成では、PHPのパフォーマンスは十分です(サンプル実行で1ページあたり約14 ms)。同じ入力を繰り返し使う場合は、ファイルキャッシュによって処理コストを完全になくせます。
テストと同等性
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で失敗します。
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スクリプトで実行します:
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)で実行し、関数ベースのアーキテクチャで使う動的な配列形状に対して、無視するパターンを少数設定しています。すべてのソースファイルが解析対象で、テストファイルは除外されます。
これらのテストで検証する構造と、差異の記録方法については、アーキテクチャを参照してください。