
# Buforowanie i minifikacja

Na etapie potoku pojawiają się trzy kwestie związane z produkcją: uniknięcie ponownej kompilacji identycznego wejścia, uniknięcie kosztu budowania kompilatora przy każdym żądaniu oraz zmniejszenie wygenerowanego CSS. Wszystkie trzy rozwiązania to pomocnicze funkcje po stronie PHP, działające wokół kompilatora.

## Buforowanie

Generowanie CSS uruchamia cały potok przy każdym wywołaniu. Gdy treść nie zmienia się między żądaniami, pamięć podręczna oparta na plikach zapisuje wynik na dysku i udostępnia go przy kolejnych wywołaniach.

Przekaż `cache` do `tw::generate()` — `true` dla domyślnego katalogu lub ciąg ścieżki dla własnego:

```php
use TailwindPHP\tw;

// Cache to the default directory: sys_get_temp_dir() . '/tailwindphp'
$css = tw::generate([
    'content' => '<div class="flex p-4">Hello</div>',
    'cache' => true,
]);

// Cache to a custom directory
$css = tw::generate([
    'content' => '<div class="flex p-4">Hello</div>',
    'cache' => '/path/to/cache',
]);

// With a time-to-live (seconds)
$css = tw::generate([
    'content' => '<div class="flex p-4">Hello</div>',
    'cache' => true,
    'cacheTtl' => 3600, // expire after 1 hour
]);
```

Katalog pamięci podręcznej jest tworzony automatycznie, jeśli jeszcze nie istnieje.

### Klucz pamięci podręcznej

Klucz jest wyprowadzany z **treści**, **konfiguracji CSS** i flagi **minify**, a następnie haszowany do nazwy pliku `tailwind_<hash>.css`. Każda zmiana znaczników, wejścia CSS lub stanu minifikacji tworzy inny klucz, a więc także inny plik.

Konfiguracja CSS uwzględniana w kluczu obejmuje wbudowane `css` oraz zawartość plików wskazanych w `importPaths`. Nie uwzględnia on dwóch elementów: plików dołączonych przez zagnieżdżone `@import` w tych plikach oraz wersji TailwindPHP. Wyczyść pamięć podręczną po edycji zagnieżdżonego importu lub aktualizacji pakietu, inaczej nadal będą udostępniane stare wyniki.

### Czas życia

`cacheTtl` określa czas życia w sekundach. Przy trafieniu w pamięci podręcznej czas modyfikacji pliku jest porównywany z aktualnym czasem; jeśli plik jest starszy niż `cacheTtl`, uznaje się to za brak trafienia i wynik jest kompilowany ponownie. Bez `cacheTtl` wpisy nigdy nie wygasają — trzeba je wyczyścić ręcznie.

### Czyszczenie pamięci podręcznej

`tw::clearCache()` (lub funkcja `clearCache()`) usuwa pliki `tailwind_*.css` z katalogu pamięci podręcznej i zwraca liczbę usuniętych plików.

```php
use TailwindPHP\tw;
use function TailwindPHP\clearCache;

$deleted = tw::clearCache();                  // default directory
$deleted = tw::clearCache('/path/to/cache');  // custom directory
clearCache('/path/to/cache');                 // function form
```

## Pamięć podręczna stanu kompilatora

Pamięć podręczna wyników pomaga tylko wtedy, gdy ta sama treść pojawia się ponownie. Gdy treść zmienia się przy każdym wywołaniu, kosztownym etapem jest samo budowanie kompilatora: rozwiązywanie `@import "tailwindcss"`, parsowanie dołączonych zasobów i gromadzenie motywu. Ten etap zależy wyłącznie od wejściowego CSS, więc można go zapisać i użyć ponownie.

Przekaż `stateCacheFile` do `tw::compile()` (lub `new TailwindCompiler($css, $options)`):

```php
use TailwindPHP\tw;

$compiler = tw::compile($themeCss, [
    'stateCacheFile' => __DIR__ . '/cache/tailwind-state.php',
]);

$css = $compiler->generateExact($html, true);
```

Przy pierwszym tworzeniu stan jest zapisywany we wskazanej ścieżce jako zwykły plik PHP, który OPcache może udostępniać między żądaniami; przy kolejnych tworzeniach jest wczytywany zamiast ponownie parsowany. Wynik jest identyczny bajt po bajcie jak w przypadku kompilatora bez pamięci podręcznej.

- Plik jest weryfikowany względem odcisku silnika (rozmiaru i czasu modyfikacji źródeł oraz zasobów TailwindPHP), klucza wyprowadzonego z wejściowego CSS oraz opcji `base` i `importSearchPaths`, a także rozmiaru i czasu modyfikacji każdego zaimportowanego pliku. Niezgodność powoduje przebudowanie i ponowny zapis, więc aktualizacja TailwindPHP lub edycja zaimportowanego pliku nie wymaga ręcznych działań.
- To Ty odpowiadasz za ścieżkę: używaj osobnego pliku dla każdego odrębnego wejścia CSS w katalogu, do którego serwer WWW może zapisywać. Zapisy są atomowe (plik tymczasowy i `rename()`).
- Wejścia korzystające z własnego `importResolver` omijają pamięć podręczną, ponieważ nie da się odcisnąć zachowania mechanizmu rozwiązywania ścieżek.
- Ta sama pamięć podręczna jest dostępna dla niższego poziomu tablicy `compile()` API jako `TailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options)`.

`tw::generate()` nie przyjmuje `stateCacheFile`; przy każdym wywołaniu buduje nowy kompilator. Gdy koszt tworzenia ma znaczenie, użyj instancji kompilatora.

## Minifikacja

Minifikacja zmniejsza wynik na potrzeby produkcji. Flaga `minify` generuje zminifikowany CSS bezpośrednio podczas serializacji, co stanowi najszybszą i najdokładniejszą metodę; `tw::minify()` uruchamia minifikator oparty na ciągach (`src/_tailwindphp/CssMinifier.php`) dla istniejącego ciągu CSS:

```php
use TailwindPHP\tw;

// Minify during generation (serializer path, preferred)
$css = tw::generate([
    'content' => '<div class="flex p-4">Hello</div>',
    'minify' => true,
]);

// Or minify an existing string (string-based post-pass)
$css = tw::generate('<div class="flex p-4">Hello</div>');
$minified = tw::minify($css);
```

Obie ścieżki tworzą równoważną strukturę, ale nie identyczne bajty. Ścieżka serializatora zachowuje selektory potomków `:not()`, które przebieg na ciągu znaków scala, dlatego w wygenerowanym wyniku preferuj flagę `minify`, a `tw::minify()` używaj w przypadku CSS otrzymanego jako ciąg znaków.

### Co robi

Obie ścieżki stosują ten sam zestaw redukcji rozmiaru:

| Krok | Efekt |
|------|--------|
| Usuwanie komentarzy | Usuwa bloki `/* … */` |
| Redukcja białych znaków | Scala ciągi białych znaków i usuwa je wokół `{ } ; : ,` oraz kombinatorów selektorów |
| Skracanie kolorów szesnastkowych | `#ffffff` → `#fff`, `#aabbcc` → `#abc` |
| Usuwanie jednostek przy zerze | `0px` → `0` (zachowuje wartości czasu `0s`/`0ms`) |
| Skracanie font-weight | `font-weight:normal` → `400`, `font-weight:bold` → `700` |
| Usuwanie pustych reguł | Usuwa selektory z pustymi blokami deklaracji |

Z założenia **nie** scala zduplikowanych selektorów ani nie łączy właściwości skróconych — oba te działania utrudniają debugowanie i mogą wpływać na kaskadę.

### CLI: `--minify` a `--optimize`

Interfejs [CLI](https://tailwindphp.inline0.dev/pl/docs/cli) udostępnia ścieżkę minifikacji serializatora za pomocą dwóch flag:

```bash
# Optimize and minify (smallest output)
tailwindphp -i ./src/app.css -o ./dist/styles.css --minify   # or -m

# Meant to optimize without minifying
tailwindphp -i ./src/app.css -o ./dist/styles.css --optimize
```

W bieżącym wydaniu `--optimize` również minifikuje, więc oba polecenia zapisują te same bajty ([#9](https://github.com/inline0/tailwindphp/issues/9)). Transformacje równoważne lightningcss są uruchamiane przy każdym buildzie niezależnie od tego, dlatego zwykły wynik (bez flagi) jest już zoptymalizowaną, czytelną postacią.

Pozostałe elementy publicznego API — `tw::generate()`, `tw::compile()`, metody inspekcji i formaty wejściowe — opisano w dokumentacji [APIreferencyjnej](https://tailwindphp.inline0.dev/pl/docs/api).
