
# Кешування та мініфікація

На етапі конвеєра виникають три завдання для виробничого середовища: уникнути повторної компіляції незмінних вхідних даних, не створювати компілятор для кожного запиту та зменшити згенерований 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` кеш не використовується, оскільки поведінку розв’язувача неможливо відстежити за відбитком.
- Той самий кеш можна використовувати з низькорівневим масивом `compile()` API як `TailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options)`.

`tw::generate()` не приймає `stateCacheFile`; він створює новий компілятор під час кожного виклику. Якщо важлива вартість створення, використовуйте екземпляр компілятора.

## Мінімізація

Мініфікація зменшує розмір результату для production. Прапорець `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 | `font-weight:normal` → `400`, `font-weight:bold` → `700` |
| Видалення порожніх правил | Вилучає селектори з порожніми блоками оголошень |

За задумом він **не** об'єднує дубльовані селектори чи скорочені властивості — це ускладнює налагодження та може вплинути на каскад.

### CLI: `--minify` проти `--optimize`

[CLI](https://tailwindphp.inline0.dev/uk/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/uk/docs/api).
