
# Cache e minificação

Três preocupações de produção surgem nas etapas finais do pipeline: evitar recompilar entradas idênticas, evitar o custo de criar um compilador em cada requisição e reduzir o CSS gerado. As três são auxiliares do lado de PHP ao redor do compilador.

## Cache

A geração de CSS executa todo o pipeline a cada chamada. Para conteúdo que não muda entre requisições, o cache baseado em arquivos grava o resultado em disco e o serve nas chamadas seguintes.

Passe `cache` para `tw::generate()` — `true` para o diretório padrão ou uma string de caminho para um diretório personalizado:

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

O diretório de cache é criado automaticamente se ainda não existir.

### Chave do cache

A chave é derivada do **conteúdo**, da **configuração CSS** e do sinalizador **minify** — tudo é transformado em hash no nome do arquivo `tailwind_<hash>.css`. Qualquer alteração na marcação, na entrada CSS ou na ativação da minificação gera uma chave diferente e, portanto, um arquivo diferente.

A configuração CSS na chave é a entrada `css` embutida mais o conteúdo dos arquivos indicados em `importPaths`. Duas entradas não são incluídas: arquivos importados por um `@import` aninhado dentro desses arquivos e a versão de TailwindPHP. Limpe o cache depois de editar uma importação aninhada ou atualizar o pacote; caso contrário, a saída antiga continuará sendo servida.

### Tempo de vida

`cacheTtl` é o tempo de vida em segundos. Quando há um acerto no cache, compara-se a data de modificação do arquivo com a hora atual; se o arquivo for mais antigo que `cacheTtl`, ele é tratado como uma falha no cache e compilado novamente. Sem `cacheTtl`, as entradas nunca expiram — limpe-as explicitamente.

### Limpeza do cache

`tw::clearCache()` (ou a função `clearCache()`) remove os arquivos `tailwind_*.css` de um diretório de cache e retorna o número de arquivos excluídos.

```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 do estado do compilador

O cache de saída só ajuda quando o mesmo conteúdo volta a ser usado. Quando o conteúdo muda a cada chamada, a parte cara é criar o próprio compilador: resolver `@import "tailwindcss"`, analisar os recursos incluídos e acumular o tema. Essa etapa depende apenas da entrada CSS, por isso pode ser armazenada e reutilizada.

Passe `stateCacheFile` para `tw::compile()` (ou `new TailwindCompiler($css, $options)`):

```php
use TailwindPHP\tw;

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

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

Na primeira criação, o estado é gravado nesse caminho como um arquivo PHP simples, que o OPcache pode compartilhar entre requisições; as criações seguintes o carregam, em vez de analisar tudo novamente. A saída é idêntica byte a byte à de um compilador sem cache.

- O arquivo é validado com base em uma impressão digital do mecanismo (o tamanho e a data de modificação das fontes e dos recursos de TailwindPHP), uma chave derivada da entrada CSS e das opções `base` e `importSearchPaths`, e o tamanho e a data de modificação de cada arquivo importado pela entrada. Qualquer divergência faz com que ele seja reconstruído e gravado novamente; assim, atualizar TailwindPHP ou editar um arquivo importado não exige nenhuma etapa manual.
- Você é responsável pelo caminho: use um arquivo para cada entrada CSS distinta, em um diretório em que o servidor Web possa gravar. As gravações são atômicas (um arquivo temporário mais `rename()`).
- Entradas que usam um `importResolver` personalizado ignoram o cache, pois não é possível criar uma impressão digital do comportamento do resolvedor.
- O mesmo cache está disponível para `TailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options)` em torno do API do array `compile()` de nível mais baixo.

`tw::generate()` não aceita `stateCacheFile`; cria um compilador novo a cada chamada. Use uma instância do compilador quando o custo de criação for relevante.

## Minificação

A minificação reduz a saída para produção. O sinalizador `minify` gera CSS minificado diretamente durante a serialização, sendo o caminho mais rápido e preciso; `tw::minify()` executa o minificador baseado em strings (`src/_tailwindphp/CssMinifier.php`) em uma string 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);
```

Os dois caminhos geram uma estrutura equivalente, mas os bytes não são idênticos. O caminho do serializador preserva seletores `:not()` descendentes que a etapa baseada em strings reduz; por isso, prefira o sinalizador `minify` para saídas geradas e use `tw::minify()` quando receber CSS como string.

### O que faz

Os dois caminhos aplicam o mesmo conjunto de reduções de tamanho:

| Etapa | Efeito |
|------|--------|
| Remoção de comentários | Remove blocos `/* … */` |
| Redução de espaços em branco | Reduz sequências de espaços em branco e os remove ao redor de `{ } ; : ,` e de combinadores de seletores |
| Redução de cores hexadecimais | `#ffffff` → `#fff`, `#aabbcc` → `#abc` |
| Remoção de unidades de zero | `0px` → `0` (preserva valores de tempo `0s`/`0ms`) |
| Redução de font-weight | `font-weight:normal` → `400`, `font-weight:bold` → `700` |
| Remoção de regras vazias | Remove seletores com blocos de declaração vazios |

Por definição, não combina seletores duplicados nem propriedades abreviadas — ambas as ações dificultam a depuração e podem afetar a cascata.

### CLI: `--minify` vs. `--optimize`

O [CLI](https://tailwindphp.inline0.dev/pt/docs/cli) expõe o caminho de minificação do serializador por meio de dois sinalizadores:

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

Na versão atual, `--optimize` também minifica, então os dois comandos gravam os mesmos bytes ([#9](https://github.com/inline0/tailwindphp/issues/9)). As transformações equivalentes às do lightningcss são executadas em toda compilação; assim, a saída simples (sem sinalizador) já é otimizada e legível.

Para ver o restante da API API pública — `tw::generate()`, `tw::compile()`, métodos de inspeção e formatos de entrada — consulte a referência de [API](https://tailwindphp.inline0.dev/pt/docs/api).
