Wydajność i testowanie
TailwindPHP stawia najpierw na poprawność. Zmiany specyficzne dla PHP, które przyspieszają działanie bez zmiany wyniku, są wdrażane i oznaczane jako @port-deviation:performance. Zgodność z TailwindCSS nie jest zakładana — jest stale weryfikowana za pomocą własnego zestawu testów Tailwind.
Wydajność
Port PHP stawia zgodność wyniku z TailwindCSS ponad surową przepustowość, a oryginalny TypeScript i tak pozostaje szybszy — JIT V8 kompiluje gorące ścieżki do kodu natywnego w sposób, któremu PHP nie dorównuje. Gdy generujesz CSS na żądanie lub dla każdej strony, używaj ponownie jednego kompilatora (zobacz generateExact()) i zachowuj stan jego inicjalizacji za pomocą stateCacheFile.
Kilka gorących ścieżek ma ręcznie dostrojone optymalizacje, które zachowują identyczny wynik:
ast.phptoCss()— gromadzi fragmenty w tablicy i wywołujeimploderaz zamiast wielokrotnie łączyć ciągi znaków; używa też wstępnie obliczonych ciągów wcięć.css-parser.php— porównuje znaki bezpośrednio, zamiast korzystać zord(), i śledzi długości buforów, zamiast ponownie obliczaćstrlen().
Oba rozwiązania są opisane za pomocą @port-deviation:performance i objęte zestawem testów — nie mogą zmienić wygenerowanego CSS.
Testy wydajności
Katalog benchmarks/ zawiera narzędzie do porównywania wyników. Uruchom je poleceniem:
composer bench # PHP vs TypeScript
composer bench:save # write benchmarks/results.json
Przykładowe wyniki na PHP 8.4.5 / Node.js v22.17.0 (Apple M1):
| Test wydajności | PHP | TypeScript |
|---|---|---|
css-parser na preflight.css |
~816 ops/s | ~15.45K ops/s (≈20× szybciej) |
toCss |
~65.85K ops/s | ~2.59M ops/s (≈39× szybciej) |
TypeScript działa szybciej przy tych operacjach niskiego poziomu, zgodnie z oczekiwaniami. W przypadku generowania pełnej strony CSS — rzeczywistego zastosowania — wydajność PHP jest wystarczająca (około 14 ms na stronę w przykładowym uruchomieniu). Przy powtarzaniu identycznych danych wejściowych pamięć podręczna plików całkowicie eliminuje ten koszt.
Testowanie i zgodność
Testy gwarantują, że port PHP generuje taki sam wynik jak TailwindCSS. Stosowane są dwa uzupełniające się podejścia.
1. Testy oparte na ekstrakcji. Skrypty w test-coverage/ analizują własne pliki .test.ts należące do TailwindCSS i wyodrębniają przypadki testowe do JSON. Następnie PHPUnit uruchamia te przypadki przez TailwindPHP i porównuje wynik z oczekiwanym CSS. Ponieważ oczekiwania pochodzą bezpośrednio z upstream, każde odejście od zachowania PHP skutkuje błędem. Testy obejmują złożone obszary: narzędzia, warianty, integrację, funkcje CSS oraz testy ui.spec na poziomie przeglądarki.
2. Ręcznie przeniesione testy jednostkowe. Prostsze pliki testowe TypeScript (AST, parsowanie CSS, uciekanie znaków, parsowanie kandydatów i wartości, …) są bezpośrednio przenoszone do PHP i umieszczane obok źródeł jako *.test.php, z zachowaniem struktury i asercji oryginałów.
Cykl to wyodrębnij → uruchom → zweryfikuj: ponownie wyodrębnij testy z aktualnej referencji TailwindCSS, uruchom zestaw, a każde odejście spowoduje błąd. Dzięki temu port pozostaje zgodny z upstream, a aktualizację TailwindCSS można zweryfikować automatycznie, zamiast sprawdzać ją ręcznie. Niezgodność powoduje błąd CI.
composer extract # re-extract test cases from the TailwindCSS reference
composer test # run the full suite
Na wydanie 1.7.0 przypada 4,427 testów zakończonych powodzeniem (referencja TailwindCSS v4.3.3):
| Zestaw | Testy | Źródło |
|---|---|---|
Wyodrębnione zestawy TailwindCSS (narzędzia 706, warianty 164, indeks 148, css-functions 64, ui.spec 68) |
1,150 | wyodrębnione z .test.ts / .spec.ts |
Pokrycie API (narzędzia, modyfikatory, warianty, dyrektywy, wtyczki, importy, @source, buforowanie, publiczne API) |
2,252 | tests/ |
| Testy jednostkowe obok źródeł (parser, AST, kandydaci, motyw, narzędzia, parser selektorów, transformacje lightningcss, minifikator) | 767 | porty *.test.php i testy specyficzne dla PHP |
| CLI (parsowanie argumentów, wynik, buildy) | 84 | tests/Cli*Test.php |
| Porty wtyczek (typografia, formularze) | 45 | *.test.php obok wtyczek |
| Biblioteki towarzyszące (clsx, tailwind-merge, CVA) | 129 | zestawy referencyjne |
Jakość kodu
Formatowanie i analiza statyczna są wykonywane za pomocą skryptów Composer:
composer lint # Pint --test (check formatting)
composer format # Pint (fix formatting)
composer analyse # PHPStan (static analysis, level 4)
composer quality # lint + analyse
PHPStan działa na poziomie 4 (phpstan.neon), z krótką listą ignorowanych wzorców dla dynamicznych struktur tablic używanych przez architekturę opartą na funkcjach. Analizowane są wszystkie pliki źródłowe, a pliki testowe są pomijane.
Opis struktury weryfikowanej przez te testy oraz zapisanych odstępstw znajdziesz w sekcji Architektura.