
# Cache e minificazione

Tre esigenze di produzione si presentano alla fine della pipeline: evitare di ricompilare input identici, evitare il costo di creare un compilatore a ogni richiesta e ridurre il CSS generato. Tutte e tre sono funzioni di supporto lato PHP intorno al compilatore.

## Memorizzazione nella cache

La generazione di CSS esegue l'intera pipeline a ogni chiamata. Per i contenuti che non cambiano tra una richiesta e l'altra, la cache basata su file salva il risultato su disco e lo restituisce alle chiamate successive.

Passate `cache` a `tw::generate()`: `true` per la directory predefinita oppure una stringa con il percorso per sceglierne una personalizzata:

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

La directory della cache viene creata automaticamente se non esiste.

### Chiave della cache

La chiave deriva dal **contenuto**, dalla **configurazione CSS** e dal flag **minify**; questi elementi vengono sottoposti a hash nel nome del file `tailwind_<hash>.css`. Qualsiasi modifica al markup, all'input CSS o all'impostazione della minificazione genera una chiave diversa e quindi un file diverso.

La configurazione CSS inclusa nella chiave è costituita dall'`css` inline e dal contenuto dei file indicati in `importPaths`. Due input non sono inclusi: i file importati tramite un `@import` annidato in quei file e la versione di TailwindPHP. Svuotate la cache dopo aver modificato un import annidato o aggiornato il pacchetto, altrimenti continuerà a essere restituito il vecchio output.

### Durata della cache

`cacheTtl` è una durata espressa in secondi. Quando si trova un risultato nella cache, l'ora di modifica del file viene confrontata con l'ora corrente; se il file è più vecchio di `cacheTtl`, viene considerato un risultato mancante e ricompilato. Se `cacheTtl` non è impostato, le voci non scadono mai: cancellatele manualmente.

### Svuotare la cache

`tw::clearCache()` (o la funzione `clearCache()`) elimina i file `tailwind_*.css` da una directory della cache e restituisce il numero di file eliminati.

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

## Cache dello stato del compilatore

La cache di output è utile solo quando torna lo stesso contenuto. Quando il contenuto cambia a ogni chiamata, la parte costosa è la creazione del compilatore: risolvere `@import "tailwindcss"`, analizzare le risorse incluse e accumulare il tema. Questa fase dipende solo dall'input CSS, quindi può essere salvata e riutilizzata.

Passate `stateCacheFile` a `tw::compile()` (o a `new TailwindCompiler($css, $options)`):

```php
use TailwindPHP\tw;

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

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

Alla prima creazione, lo stato viene scritto in quel percorso come file PHP semplice, che OPcache può condividere tra le richieste; le creazioni successive lo caricano invece di analizzarlo di nuovo. L'output è identico byte per byte a quello di un compilatore senza cache.

- Il file viene convalidato rispetto a un'impronta del motore (dimensione e mtime dei sorgenti e delle risorse di TailwindPHP), a una chiave derivata dall'input CSS e dalle opzioni `base` e `importSearchPaths`, nonché a dimensione e mtime di ogni file importato dall'input. Se qualcosa non corrisponde, viene ricostruito e riscritto: non serve alcun intervento manuale dopo aver aggiornato TailwindPHP o modificato un file importato.
- Il percorso è a vostra scelta: usate un file per ogni input CSS distinto, in una directory in cui il server web possa scrivere. Le scritture sono atomiche (file temporaneo più `rename()`).
- Gli input che usano un `importResolver` personalizzato ignorano la cache, perché non è possibile calcolare l'impronta del comportamento del resolver.
- La stessa cache è disponibile per l'array `compile()` di livello inferiore API come `TailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options)`.

`tw::generate()` non accetta `stateCacheFile`: crea un nuovo compilatore a ogni chiamata. Se il costo di creazione è rilevante, usate un'istanza del compilatore.

## Minimizzazione

La minificazione riduce l'output per la produzione. Il flag `minify` genera direttamente CSS minificato durante la serializzazione, quindi è il metodo più rapido e preciso; `tw::minify()` esegue il minificatore basato su stringhe (`src/_tailwindphp/CssMinifier.php`) su una stringa CSS esistente:

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

I due metodi producono una struttura equivalente, ma non byte identici. Il metodo del serializzatore mantiene i selettori `:not()` discendenti che il passaggio sulle stringhe accorpa; quindi, per l'output generato, preferite il flag `minify` e riservate `tw::minify()` a CSS che arrivano come stringa.

### Cosa fa

Entrambi i metodi applicano lo stesso insieme di riduzioni delle dimensioni:

| Passaggio | Effetto |
|------|--------|
| Rimozione dei commenti | Elimina i blocchi `/* … */` |
| Compattazione degli spazi | Riduce le sequenze di spazi e li rimuove intorno a `{ } ; : ,` e ai combinatori dei selettori |
| Accorciamento dei colori esadecimali | `#ffffff` → `#fff`, `#aabbcc` → `#abc` |
| Rimozione delle unità dai valori zero | `0px` → `0` (mantiene i valori temporali `0s`/`0ms`) |
| Accorciamento di font-weight | `font-weight:normal` → `400`, `font-weight:bold` → `700` |
| Rimozione delle regole vuote | Elimina i selettori con blocchi di dichiarazioni vuoti |

Per scelta progettuale non unisce i selettori duplicati né combina le proprietà shorthand: entrambe le operazioni rendono più difficile il debug e possono influire sulla cascata.

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

[CLI](https://tailwindphp.inline0.dev/it/docs/cli) espone il metodo di minificazione del serializzatore tramite due 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
```

Nella versione attuale, anche `--optimize` esegue la minificazione, quindi entrambi i comandi scrivono gli stessi byte ([#9](https://github.com/inline0/tailwindphp/issues/9)). Le trasformazioni equivalenti a lightningcss vengono eseguite a ogni build in entrambi i casi, quindi l'output semplice (senza flag) è già ottimizzato e leggibile.

Per il resto dell'API pubblico — `tw::generate()`, `tw::compile()`, metodi di ispezione e formati di input — consultate il riferimento [API](https://tailwindphp.inline0.dev/it/docs/api).
