
# Кеширане и минифициране

Три задачи за продукционна среда възникват в края на процеса: да се избегне повторно компилиране на един и същ вход, да не се плаща цената за изграждане на компилатора при всяка заявка и да се намали генерираният CSS. И трите се решават с помощни функции PHP около компилатора.

## Кеширане

Генерирането на CSS изпълнява целия процес при всяко извикване. Ако съдържанието не се променя между заявките, файловият кеш записва резултата на диска и го предоставя при следващите извиквания.

Подайте `cache` на `tw::generate()` – `true` за директорията по подразбиране или низ с път към персонализирана директория:

```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
]);
```

Директорията на кеша се създава автоматично, ако не съществува.

### Ключ на кеша

Ключът се извежда от **съдържанието**, **конфигурацията CSS** и флага **minify** и се хешира в името на файла `tailwind_<hash>.css`. Всяка промяна в маркировката, входа CSS или състоянието на минифицирането създава различен ключ и съответно различен файл.

Конфигурацията CSS в ключа включва вграденото `css` и съдържанието на файловете, посочени в `importPaths`. Два входа не участват: файловете, включени от вложен `@import` в тези файлове, и версията на TailwindPHP. Изчистете кеша след редактиране на вложен импорт или надграждане на пакета, иначе ще продължи да се предоставя старият резултат.

### Срок на валидност

`cacheTtl` е срокът на валидност в секунди. При попадение в кеша времето на промяна на файла се сравнява с текущото време; ако файлът е по-стар от `cacheTtl`, кешът се счита за пропуснат и съдържанието се компилира отново. Без `cacheTtl` записите не изтичат – изчиствайте ги изрично.

### Изчистване на кеша

`tw::clearCache()` (или функцията `clearCache()`) премахва файловете `tailwind_*.css` от директория на кеша и връща броя на изтритите файлове.

```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
```

## Кеш на състоянието на компилатора

Кешът за изход помага само когато едно и също съдържание се подава отново. Когато съдържанието се променя при всяко извикване, скъпата част е изграждането на самия компилатор: разрешаване на `@import "tailwindcss"`, анализиране на включените ресурси и натрупване на темата. Този етап зависи само от входа CSS, затова може да се съхрани и използва повторно.

Подайте `stateCacheFile` на `tw::compile()` (или `new TailwindCompiler($css, $options)`):

```php
use TailwindPHP\tw;

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

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

При първоначалното създаване състоянието се записва на този път като обикновен файл PHP, който OPcache може да споделя между заявките; следващите създавания го зареждат, вместо да анализират отново. Резултатът е побайтово идентичен с този на компилатор без кеш.

- Файлът се валидира спрямо отпечатък на двигателя (размера и времето на последна промяна на изходните файлове и ресурсите на TailwindPHP), ключ, извлечен от входа CSS и опциите `base` и `importSearchPaths`, както и размера и времето на последна промяна на всеки файл, импортиран от входа. При несъответствие файлът се изгражда отново и се презаписва, така че не е необходима ръчна стъпка при надграждане на TailwindPHP или редактиране на импортиран файл.
- Вие определяте пътя: използвайте по един файл за всеки отделен вход CSS в директория, в която уеб сървърът може да записва. Записите са атомарни (временен файл плюс `rename()`).
- Входовете, които използват персонализиран `importResolver`, заобикалят кеша, защото поведението на резолвера не може да бъде включено в отпечатъка.
- Същият кеш може да се използва и около масива API на ниско ниво `compile()` като `TailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options)`.

`tw::generate()` не приема `stateCacheFile`; при всяко извикване създава нов компилатор. Когато разходът за създаване е важен, използвайте екземпляр на компилатора.

## Минимизиране

Минификацията намалява размера на изхода за продукционна среда. Флагът `minify` генерира минифициран CSS директно по време на сериализацията, което го прави най-бързия и най-прецизен подход; `tw::minify()` стартира базиран на низове минификатор (`src/_tailwindphp/CssMinifier.php`) върху съществуващ низ 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);
```

Двата подхода създават еквивалентна структура, но не и еднакви байтове. Подходът чрез сериализатора запазва селекторите за наследници `:not()`, които обработката на низа слива, затова предпочитайте флага `minify` за генериран изход и запазете `tw::minify()` за CSS, подаден като низ.

### Какво прави

И двата подхода прилагат един и същ набор от намаления на размера:

| Стъпка | Ефект |
|------|--------|
| Премахване на коментари | Премахва блоковете `/* … */` |
| Свиване на интервалите | Свива последователностите от интервали и премахва интервалите около `{ } ; : ,` и комбинаторите на селектори |
| Съкращаване на шестнадесетичните цветове | `#ffffff` → `#fff`, `#aabbcc` → `#abc` |
| Премахване на единиците при нула | `0px` → `0` (запазва времевите стойности `0s`/`0ms`) |
| Съкращаване на дебелината на шрифта | `font-weight:normal` → `400`, `font-weight:bold` → `700` |
| Премахване на празни правила | Премахва селекторите с празни блокове за декларации |

По замисъл не се сливат дублиращи се селектори и не се комбинират съкратени свойства — това затруднява отстраняването на грешки и може да засегне каскадата.

### CLI: `--minify` срещу `--optimize`

[CLI](https://tailwindphp.inline0.dev/bg/docs/cli) предоставя достъп до пътя за минификация на сериализатора чрез два флага:

```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
```

В текущото издание `--optimize` също минифицира, така че двете команди записват едни и същи байтове ([#9](https://github.com/inline0/tailwindphp/issues/9)). Трансформациите, еквивалентни на lightningcss, се изпълняват при всяко изграждане и в двата случая, така че обикновеният изход (без флаг) вече е оптимизиран и лесен за четене.

За останалата част от публичния API — `tw::generate()`, `tw::compile()`, методите за проверка и входните формати — вижте справочника [API](https://tailwindphp.inline0.dev/bg/docs/api).
