Продуктивність і тестування
TailwindPHP насамперед оптимізує коректність. Зміни, специфічні для PHP, що пришвидшують роботу без зміни результату, застосовуються та позначаються як @port-deviation:performance. Відповідність TailwindCSS не вважається гарантованою — її постійно перевіряють за власним набором тестів Tailwind.
Продуктивність
Порт PHP надає перевагу відповідності результату TailwindCSS над максимальною швидкістю, а оригінал TypeScript у будь-якому разі працює швидше: JIT-компілятор V8 перетворює найгарячіші ділянки коду на нативний код так, як PHP не може. Для CSS, що генерується на кожен запит або сторінку, повторно використовуйте один компілятор (див. 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× швидше) |
toCss |
~65.85K ops/s | ~2.59M ops/s (≈39× швидше) |
TypeScript швидший у таких низькорівневих операціях, як і очікувалося. Для генерації CSS цілої сторінки — основного сценарію використання — швидкодія PHP достатня (приблизно 14 мс на сторінку в пробному запуску). Для повторення того самого вводу витрати повністю усуває файловий кеш.
Тестування та відповідність
Тести гарантують, що порт PHP дає такий самий результат, як TailwindCSS. Для цього разом застосовуються два підходи.
1. Тести на основі видобутих даних. Скрипти в test-coverage/ розбирають власні файли .test.ts проєкту TailwindCSS і видобувають тестові випадки в JSON. Потім PHPUnit передає їх у TailwindPHP і порівнює результат з очікуваним CSS. Очікувані результати беруться безпосередньо з upstream, тому будь-яке відхилення поведінки PHP одразу стає помітним як помилка. Ці тести охоплюють складні ділянки: утиліти, варіанти, інтеграцію, функції CSS і браузерні тести ui.spec.
2. Перенесені вручну модульні тести. Простіші тестові файли TypeScript (AST, розбір CSS, екранування, розбір кандидатів, розбір значень тощо) переносяться безпосередньо в PHP і зберігаються поряд із вихідним кодом як *.test.php, відтворюючи структуру та перевірки оригіналів.
Цикл такий: видобути → запустити → перевірити. Дані знову видобуваються з поточного еталона TailwindCSS, набір тестів запускається, і будь-яке відхилення виявляється помилкою. Так порт не відстає від upstream, а оновлення TailwindCSS можна перевірити автоматично, а не переглядати вручну. Відхилення зупиняють CI.
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 (utilities 706, variants 164, index 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 |
| Порти плагінів (типографіка, форми) | 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), із коротким списком ігнорованих шаблонів для динамічних форм масивів, які використовує архітектура на основі функцій. Аналізуються всі файли вихідного коду; тестові файли виключено.
Щоб дізнатися, яку структуру перевіряють ці тести та де фіксуються відхилення, див. Архітектура.