Перейти к содержимому

Производительность и тестирование

TailwindPHP в первую очередь оптимизируется ради корректности. Если изменение для PHP ускоряет работу и не меняет результат, его применяют и помечают как @port-deviation:performance. Соответствие TailwindCSS не предполагается — оно постоянно проверяется набором тестов Tailwind.

Производительность

Порт PHP ставит соответствие результатам TailwindCSS выше максимальной пропускной способности, а исходный TypeScript в любом случае быстрее: JIT-компилятор V8 компилирует часто выполняемые участки в машинный код так, как PHP не может. Для CSS, генерируемого при каждом запросе или для каждой страницы, используйте один компилятор повторно (см. generateExact()) и сохраняйте его состояние после создания с помощью stateCacheFile.

Некоторые часто выполняемые участки кода оптимизированы вручную так, чтобы сохранять идентичный результат:

  • ast.php toCss() — накапливает фрагменты в массиве и один раз вызывает 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. Поскольку эталонные результаты берутся непосредственно из исходного проекта, любое расхождение в поведении PHP обнаруживается как ошибка. Эти тесты охватывают сложные области: утилиты, варианты, интеграцию, функции CSS и тесты уровня браузера ui.spec.

2. Перенесённые вручную модульные тесты. Более простые тестовые файлы TypeScript (AST, разбор CSS, экранирование, разбор кандидатов и значений, …) напрямую перенесены в 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 (эталон TailwindCSS v4.3.3) пройдено 4,427 тестов:

Набор Тесты Источник
Извлечённые наборы TailwindCSS (утилиты 706, варианты 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); для динамических форм массивов, используемых в архитектуре на основе функций, задан небольшой список игнорируемых шаблонов. Анализируются все исходные файлы, тестовые файлы исключены.

О структуре, проверяемой этими тестами, и регистрации отклонений см. в разделе Архитектура.