
# キャッシュと圧縮

本番環境では、パイプラインの最後にある3つの課題に対処します。同じ入力の再コンパイルを避けること、リクエストごとのコンパイラー構築コストを避けること、生成された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`で指定されたファイルの内容です。キーに含まれない入力が2つあります。これらのファイル内のネストされた`@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ごとに1つのファイルを使い、ウェブサーバーが書き込めるディレクトリに配置してください。書き込みは一時ファイルと`rename()`を使ってアトミックに行われます。
- カスタム`importResolver`を使う入力は、リゾルバーの動作をフィンガープリント化できないため、キャッシュを迂回します。
- 同じキャッシュは、低レベルの`compile()`配列APIの`TailwindPHP\StateCache\compileCssCached($css, $cacheFile, $options)`としても利用できます。

`tw::generate()`は`stateCacheFile`を受け取らず、呼び出すたびに新しいコンパイラーを構築します。構築コストが問題になる場合は、コンパイラーのインスタンスを使ってください。

## 圧縮

ミニファイは本番環境向けに出力を縮小します。`minify`フラグはシリアライズ時にミニファイ済みCSSを直接出力するため、最速かつ最も正確な方法です。`tw::minify()`は既存のCSS文字列に対して、文字列ベースのミニファイア（`src/_tailwindphp/CssMinifier.php`）を実行します。

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

2つの方法で得られる構造は同等ですが、バイト列は同一ではありません。シリアライザー方式では、文字列処理方式がまとめてしまう子孫`:not()`セレクターが保持されます。そのため、生成する出力には`minify`フラグを使い、文字列として渡されるCSSには`tw::minify()`を使ってください。

### 処理内容

どちらの方法でも、同じサイズ削減処理を適用します。

| 手順 | 効果 |
|------|--------|
| コメントの削除 | `/* … */`ブロックを取り除きます |
| 空白の圧縮 | 連続する空白をまとめ、`{ } ; : ,`やセレクターの結合子の前後から空白を取り除きます |
| 16進数カラーの短縮 | `#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/ja/docs/cli)では、2つのフラグを使ってシリアライザーのミニファイ経路を利用できます。

```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/ja/docs/api)を参照してください。
