Przejdź do treści

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.php toCss() — gromadzi fragmenty w tablicy i wywołuje implode raz 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ć z ord(), 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:

Powłoka
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.

Powłoka
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:

Powłoka
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.