
# Performance und Tests

TailwindPHP optimiert vorrangig auf Korrektheit. Wenn eine spezifische Änderung für PHP die Leistung steigert, ohne die Ausgabe zu verändern, wird sie übernommen und als `@port-deviation:performance` gekennzeichnet. Die Parität mit TailwindCSS wird nicht vorausgesetzt, sondern laufend anhand der eigenen Testsuite von Tailwind überprüft.

## Leistung

Beim PHP-Port hat die Übereinstimmung mit der TailwindCSS-Ausgabe Vorrang vor dem reinen Durchsatz; das Original TypeScript bleibt ohnehin schneller — V8s JIT kompiliert häufig ausgeführte Pfade zu nativem Code, was PHP nicht erreichen kann. Wenn CSS pro Anfrage oder Seite erzeugt wird, verwende einen Compiler erneut (siehe [generateExact()](https://tailwindphp.inline0.dev/de/docs/api#accumulating-vs-exact-generation)) und speichere seinen Konstruktionszustand mit [`stateCacheFile`](https://tailwindphp.inline0.dev/de/docs/advanced/caching#compiler-state-cache).

Einige häufig ausgeführte Pfade enthalten von Hand optimierte Stellen, die **identische Ausgaben gewährleisten**:

- **`ast.php` `toCss()`** — sammelt Fragmente in einem Array und führt `implode` einmal aus, statt wiederholt Zeichenfolgen zu verketten, und verwendet vorab berechnete Einrückungszeichenfolgen.
- **`css-parser.php`** — vergleicht Zeichen direkt, statt `ord()` zu durchlaufen, und erfasst Pufferlängen, statt `strlen()` neu zu berechnen.

Beide sind mit `@port-deviation:performance` dokumentiert und an die Testsuite gebunden — sie können die erzeugte CSS nicht verändern.

### Benchmarks

Das Verzeichnis `benchmarks/` enthält ein Vergleichsprogramm. Führe es so aus:

```bash
composer bench         # PHP vs TypeScript
composer bench:save    # write benchmarks/results.json
```

Beispielergebnisse mit PHP 8.4.5 / Node.js v22.17.0 (Apple M1):

| Benchmark | PHP | TypeScript |
|-----------|-----|------------|
| `css-parser` auf preflight.css | ~816 ops/s | ~15.45K ops/s (≈20× schneller) |
| `toCss` | ~65.85K ops/s | ~2.59M ops/s (≈39× schneller) |

TypeScript ist bei diesen Low-Level-Operationen erwartungsgemäß schneller. Für die Erzeugung von CSS für ganze Seiten — den eigentlichen Anwendungsfall — ist die Leistung von PHP ausreichend (im Beispiel etwa 14 ms pro Seite). Bei wiederholter identischer Eingabe entfallen die Kosten dank des [Datei-Caches](https://tailwindphp.inline0.dev/de/docs/advanced/caching) vollständig.

## Tests und Parität

Die Tests stellen sicher, dass der PHP-Port dieselbe Ausgabe wie TailwindCSS erzeugt. Dafür kommen zwei Ansätze zusammen.

**1. Extraktionsbasierte Tests.** Skripte in `test-coverage/` lesen TailwindCSSs eigene `.test.ts`-Dateien ein und extrahieren die Testfälle nach JSON. PHPUnit führt diese Fälle über TailwindPHP aus und vergleicht die Ausgabe mit dem erwarteten CSS. Da die erwarteten Ergebnisse direkt aus dem Upstream-Projekt stammen, zeigt jeder Unterschied im Verhalten von PHP einen Fehler an. Abgedeckt sind komplexe Bereiche: Utilities, Varianten, Integration, CSS-Funktionen und Tests auf Browserebene mit `ui.spec`.

**2. Manuell portierte Unit-Tests.** Einfachere TypeScript-Testdateien (AST, CSS-Parsing, Escaping, Parsing von Kandidaten und Werten, …) werden direkt nach PHP portiert und liegen als `*.test.php` neben ihrer jeweiligen Quelldatei. Dabei werden Aufbau und Assertions der Originale übernommen.

Der Ablauf lautet **extrahieren → ausführen → prüfen**: Extrahiere die Tests erneut aus der aktuellen TailwindCSS-Referenz und führe die Testsuite aus. Jede Abweichung schlägt fehl. So bleibt der Port mit dem Upstream-Projekt synchron, und ein TailwindCSS-Update lässt sich mechanisch statt durch Sichtprüfung validieren. Bei Abweichungen schlägt CI fehl.

```bash
composer extract   # re-extract test cases from the TailwindCSS reference
composer test      # run the full suite
```

Seit Release 1.7.0 sind **4.427 Tests bestanden** (TailwindCSS-Referenz v4.3.3):

| Testsuite | Tests | Quelle |
|-------|-------|--------|
| Extrahierte TailwindCSS-Testsuites (Utilities 706, Varianten 164, Index 148, CSS-Funktionen 64, `ui.spec` 68) | 1,150 | extrahiert aus `.test.ts` / `.spec.ts` |
| API-Abdeckung (Utilities, Modifikatoren, Varianten, Direktiven, Plugins, Imports, `@source`, Caching, öffentliche API) | 2,252 | `tests/` |
| Unit-Tests neben dem Quellcode (Parser, AST, Kandidaten, Theme, Hilfsfunktionen, Selektor-Parser, lightningcss-Transformationen, Minifier) | 767 | `*.test.php`-Ports und PHP-spezifische Tests |
| CLI (Argument-Parsing, Ausgabe, Builds) | 84 | `tests/Cli*Test.php` |
| Plugin-Ports (Typography, Forms) | 45 | `*.test.php` neben den Plugins |
| Begleitbibliotheken (clsx, tailwind-merge, CVA) | 129 | Referenztestsuites |

## Codequalität

Formatierung und statische Analyse laufen über Composer-Skripte:

```bash
composer lint      # Pint --test  (check formatting)
composer format    # Pint         (fix formatting)
composer analyse   # PHPStan      (static analysis, level 4)
composer quality   # lint + analyse
```

PHPStan läuft auf Level 4 (`phpstan.neon`), mit einer kurzen Liste ignorierter Muster für die dynamischen Array-Strukturen der funktionsbasierten Architektur. Alle Quelldateien werden analysiert; Testdateien sind ausgeschlossen.

Die Struktur, die diese Tests prüfen, und die dokumentierten Abweichungen findest du unter [Architektur](https://tailwindphp.inline0.dev/de/docs/advanced/architecture).
