
# Almacenamiento en caché y minificación

Tres aspectos de producción entran en juego al final del proceso: evitar recompilar entradas idénticas, evitar el coste de crear un compilador en cada solicitud y reducir el tamaño del CSS generado. Los tres son ayudantes del lado de PHP que complementan el compilador.

## Caché

La generación de CSS ejecuta todo el proceso en cada llamada. Si el contenido no cambia entre solicitudes, la caché basada en archivos guarda el resultado en el disco y lo sirve en las llamadas posteriores.

Pase `cache` a `tw::generate()`: `true` para el directorio predeterminado o una ruta para usar otro:

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

El directorio de la caché se crea automáticamente si no existe.

### Clave de caché

La clave se deriva del **contenido**, la **configuración CSS** y el indicador **minify**, y se usa como nombre del archivo `tailwind_<hash>.css`. Cualquier cambio en el marcado, la entrada de CSS o la activación de la minificación genera una clave diferente y, por tanto, otro archivo.

La configuración de CSS incluida en la clave consta del `css` en línea y el contenido de los archivos indicados en `importPaths`. Hay dos entradas que no se incluyen: los archivos incorporados mediante un `@import` anidado en esos archivos y la versión de TailwindPHP. Vacíe la caché después de editar una importación anidada o actualizar el paquete; de lo contrario, se seguirá sirviendo la salida anterior.

### Tiempo de vida

`cacheTtl` es el tiempo de vida en segundos. Cuando hay un acierto de caché, se compara la fecha de modificación del archivo con la hora actual; si es anterior a `cacheTtl`, se considera un fallo y se vuelve a compilar. Si no se especifica `cacheTtl`, las entradas nunca caducan: deberá borrarlas explícitamente.

### Borrar la caché

`tw::clearCache()` (o la función `clearCache()`) elimina los archivos `tailwind_*.css` del directorio de caché y devuelve el número de archivos borrados.

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

## Caché del estado del compilador

La caché de salida solo ayuda cuando se repite el mismo contenido. Si el contenido cambia en cada llamada, lo costoso es crear el compilador: resolver `@import "tailwindcss"`, analizar los recursos incluidos y acumular el tema. Esa fase solo depende de la entrada CSS, por lo que se puede guardar y reutilizar.

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

```php
use TailwindPHP\tw;

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

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

Al crear el compilador por primera vez, el estado se guarda en esa ruta como un archivo PHP sin procesar, que OPcache puede compartir entre solicitudes; las siguientes instancias lo cargan en vez de analizarlo de nuevo. La salida es idéntica byte a byte a la de un compilador sin caché.

- El archivo se valida con una huella del motor (el tamaño y la fecha de modificación de los archivos fuente y recursos de TailwindPHP), una clave derivada de la entrada CSS y las opciones `base` y `importSearchPaths`, además del tamaño y la fecha de modificación de cada archivo importado por la entrada. Si algo no coincide, se vuelve a generar y guardar; por eso no hace falta ningún paso manual al actualizar TailwindPHP o editar un archivo importado.
- Usted elige la ruta: use un archivo por cada CSS de entrada distinto, en un directorio donde el servidor web pueda escribir. Las escrituras son atómicas (un archivo temporal más `rename()`).
- Las entradas que usan un `importResolver` personalizado omiten la caché, porque no se puede calcular la huella del comportamiento del resolver.
- La misma caché está disponible para la matriz API `compile()` de nivel inferior como `TailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options)`.

`tw::generate()` no acepta `stateCacheFile`: crea un compilador nuevo en cada llamada. Si le preocupa el coste de creación, use una instancia del compilador.

## Minificación

La minificación reduce el tamaño de la salida para producción. El indicador `minify` genera CSS minificado directamente durante la serialización, por lo que es la opción más rápida y precisa; `tw::minify()` ejecuta el minificador basado en cadenas (`src/_tailwindphp/CssMinifier.php`) sobre una cadena CSS existente:

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

Las dos opciones producen una estructura equivalente, pero no bytes idénticos. La serialización conserva los selectores `:not()` de los descendientes, que el proceso con cadenas contrae. Por eso, para la salida generada, prefiera el indicador `minify` y reserve `tw::minify()` para el CSS que ya reciba como cadena.

### Qué hace

Ambas opciones aplican las mismas reducciones de tamaño:

| Paso | Efecto |
|------|--------|
| Eliminar comentarios | Elimina los bloques `/* … */` |
| Reducir espacios en blanco | Reduce las secuencias de espacios en blanco y los elimina alrededor de `{ } ; : ,` y los combinadores de selectores |
| Acortar colores hexadecimales | `#ffffff` → `#fff`, `#aabbcc` → `#abc` |
| Eliminar unidades de cero | `0px` → `0` (conserva los valores de tiempo `0s`/`0ms`) |
| Acortar font-weight | `font-weight:normal` → `400`, `font-weight:bold` → `700` |
| Eliminar reglas vacías | Elimina los selectores cuyos bloques de declaraciones están vacíos |

Por diseño, no combina selectores duplicados ni propiedades abreviadas; ambas cosas dificultan la depuración y pueden afectar la cascada.

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

El [CLI](https://tailwindphp.inline0.dev/es/docs/cli) ofrece la opción de minificación del serializador mediante dos indicadores:

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

En la versión actual, `--optimize` también minifica, de modo que ambos comandos escriben los mismos bytes ([#9](https://github.com/inline0/tailwindphp/issues/9)). Las transformaciones equivalentes a lightningcss se ejecutan en cada compilación; por eso, la salida sin indicadores ya está optimizada y es legible.

Para el resto de la API pública — `tw::generate()`, `tw::compile()`, métodos de inspección y formatos de entrada — consulte la [referencia de API](https://tailwindphp.inline0.dev/es/docs/api).
