# 機能設計書 56-Segment Cache

## 概要

本ドキュメントは、Next.jsのSegment Cacheの機能設計を記述する。Segment CacheはApp Routerにおけるルートセグメント単位のプリフェッチキャッシュ機構であり、ページ遷移前にセグメント単位でデータを取得・キャッシュすることで高速なクライアントサイドナビゲーションを実現する。

### 本機能の処理概要

**業務上の目的・背景**：従来のプリフェッチはページ全体のRSCペイロードを一括取得していたが、大規模なアプリケーションでは不要なデータの取得が発生しパフォーマンスに影響する。Segment CacheはApp Routerのセグメント階層構造を活用し、各セグメント（layout, page, loading等）単位で独立してプリフェッチ・キャッシュすることで、必要最小限のデータ取得と効率的なキャッシュ管理を実現する。

**機能の利用シーン**：`<Link>`コンポーネントや`router.prefetch()`によるプリフェッチ時にSegment Cacheが使用される。ユーザーがリンクをホバーしたりビューポートに入ったときにセグメント単位でプリフェッチが実行され、実際のナビゲーション時にキャッシュからデータが取得される。

**主要な処理内容**：
1. RouteCacheKeyの生成（パス名とsearchの正規化）
2. セグメントリクエストキーの生成（ファイルシステム安全なエンコーディング）
3. プリフェッチタスクのスケジューリングと優先度管理
4. ツリープリフェッチ（Route Tree全体）とセグメントプリフェッチの実行
5. LRUキャッシュによるメモリ管理とエビクション
6. VaryPathによるダイナミックパラメータの管理
7. ステールタイム管理（静的/動的ルートで異なるTTL）
8. BFCacheとの統合

**関連システム・外部連携**：App RouterのRSCフェッチ機構、サーバーサイドのcollect-segment-data API、FlightRouterState、IncrementalCache。

**権限による制御**：特にロールや権限による制御は行われない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | バックグラウンドで動作するキャッシュ機構のため特定画面なし |

## 機能種別

キャッシュ管理 / プリフェッチ / データ取得

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| href | string | Yes | プリフェッチ対象のURL | URL解析可能であること |
| nextUrl | string \| null | No | インターセプトルート用のヘッダー値 | - |
| treeAtTimeOfPrefetch | FlightRouterState | Yes | プリフェッチ時のルーターステートツリー | - |
| fetchStrategy | PrefetchTaskFetchStrategy | Yes | 動的データも含めてフェッチするか | - |
| onInvalidate | (() => void) \| null | No | キャッシュ無効化時のコールバック | - |

### 入力データソース

- `<Link>`コンポーネントまたは`router.prefetch()`からのプリフェッチリクエスト
- サーバーからのRSCレスポンス（ツリープリフェッチ、セグメントプリフェッチ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CacheMap | CacheMap | セグメントキーからキャッシュ値へのマッピング |
| PrefetchSubtaskResult | PrefetchSubtaskResult | プリフェッチ結果（成功/失敗/キャッシュヒット） |

### 出力先

- インメモリキャッシュ（CacheMap）
- ナビゲーション時にFlightRouterStateとして消費される

## 処理フロー

### 処理シーケンス

```
1. prefetch(href, nextUrl, tree, strategy, onInvalidate) 呼び出し
   └─ createPrefetchURL でURL検証
2. createCacheKey(url.href, nextUrl) でキャッシュキー生成
   └─ NormalizedPathname + NormalizedSearch
3. schedulePrefetchTask でプリフェッチタスクをキューに追加
   └─ 優先度: PrefetchPriority.Default
4. スケジューラがタスクを処理
   ├─ ツリープリフェッチ: RSC_HEADER + NEXT_ROUTER_PREFETCH_HEADER
   └─ セグメントプリフェッチ: NEXT_ROUTER_SEGMENT_PREFETCH_HEADER
5. レスポンス処理
   ├─ TreePrefetch: ルート全体の構造情報
   ├─ SegmentPrefetch: 個別セグメントのRSCデータ
   └─ VaryParams: ダイナミックパラメータのバリエーション
6. キャッシュ格納
   ├─ CacheMapに格納（LRU管理）
   └─ ステールタイム設定（Static/Dynamic）
```

### フローチャート

```mermaid
flowchart TD
    A[Link/router.prefetch] --> B[prefetch 関数]
    B --> C[createPrefetchURL]
    C --> D{URL 有効?}
    D -->|No| E[処理中断]
    D -->|Yes| F[createCacheKey]
    F --> G[schedulePrefetchTask]
    G --> H[スケジューラ処理]
    H --> I{タスクタイプ}
    I -->|Tree Prefetch| J[RSC ツリーフェッチ]
    I -->|Segment Prefetch| K[RSC セグメントフェッチ]
    J --> L[CacheMap 格納]
    K --> L
    L --> M{LRU エビクション必要?}
    M -->|Yes| N[古いエントリ削除]
    M -->|No| O[キャッシュ完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-01 | セグメント単位キャッシュ | 各セグメント（layout, page等）は独立してキャッシュされる | 常時 |
| BR-56-02 | LRUエビクション | キャッシュサイズ上限に達した場合、最も使用されていないエントリから削除 | CacheMap使用時 |
| BR-56-03 | ステールタイム | 静的ルート: STATIC_STALETIME_MS、動的ルート: DYNAMIC_STALETIME_MS | ルートタイプに依存 |
| BR-56-04 | ファイルシステム安全エンコーディング | セグメントキーはファイルシステムとURL安全な文字列にエンコード | 常時 |
| BR-56-05 | PAGE_SEGMENT_KEYの特別処理 | ページセグメントのsearchParamsはキーから除去し別管理 | PAGE_SEGMENT_KEYで始まるセグメント |
| BR-56-06 | 動的パラメータエンコード | 動的セグメントは`$paramType$name`形式でエンコード | 動的セグメントの場合 |

### 計算ロジック

- セグメントリクエストキー: `parentKey + '/' + slotKey`（children以外の並列ルートは`@parallelRouteKey/`プレフィックス）
- ファイルシステム安全エンコード: 単純な英数字+`-_@`はそのまま、それ以外はbase64urlエンコードし`!`プレフィックス
- キャッシュキー: URL.href + nextUrlの組み合わせ

## データベース操作仕様

該当なし（インメモリキャッシュ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | URL無効 | prefetchのhrefが不正なURL | プリフェッチ中断（静かに失敗） |
| - | フェッチエラー | RSCフェッチ中のネットワークエラー | タスクを失敗としてマーク |
| - | キャッシュミス | ナビゲーション時にキャッシュにデータがない | フォールバックでフルフェッチ |

### リトライ仕様

- プリフェッチタスクはonInvalidateコールバックで再スケジュール可能
- 自動リトライは行われない

## トランザクション仕様

該当なし

## パフォーマンス要件

- LRUキャッシュによるメモリ使用量の制限
- セグメント単位の細粒度プリフェッチにより不要なデータ転送を削減
- 優先度ベースのスケジューリングで重要なプリフェッチを先に処理

## セキュリティ考慮事項

- サーバーからのRSCレスポンスはRSC_CONTENT_TYPE_HEADERで検証
- NEXT_DID_POSTPONE_HEADERによるPPR対応

## 備考

- Segment Cacheは実験的機能として段階的に展開されている
- BFCache（ブラウザのBack/Forward Cache）との統合もサポート
- `convertSegmentPathToStaticExportFilename`による静的エクスポート時のファイル名生成もサポート

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/next/src/client/components/segment-cache/types.ts` | PrefetchPriority, PrefetchTaskFetchStrategy等の型定義 |
| 1-2 | cache-key.ts | `packages/next/src/client/components/segment-cache/cache-key.ts` | NormalizedPathname, NormalizedSearch, RouteCacheKey型 |
| 1-3 | segment-value-encoding.ts | `packages/next/src/shared/lib/segment-cache/segment-value-encoding.ts` | **14-48行目**: セグメントリクエストキーの生成ロジック、**50-68行目**: キー連結 |

**読解のコツ**: `Opaque<K, T>`パターンはTypeScriptの公称型（nominal type）をシミュレートし、異なるキー型の混同を防いでいる。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | prefetch.ts | `packages/next/src/client/components/segment-cache/prefetch.ts` | **27-47行目**: `prefetch`関数 - エントリーポイント |

**主要処理フロー**:
1. **34行目**: `createPrefetchURL(href)` でURL検証
2. **39行目**: `createCacheKey(url.href, nextUrl)` でキャッシュキー生成
3. **40-46行目**: `schedulePrefetchTask` でスケジューラに登録

#### Step 3: キャッシュ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cache.ts | `packages/next/src/client/components/segment-cache/cache.ts` | メインキャッシュ実装 - CacheMap操作、フェッチ処理 |
| 3-2 | cache-map.ts | `packages/next/src/client/components/segment-cache/cache-map.ts` | CacheMap型とCRUD操作、有効期限管理 |
| 3-3 | lru.ts | `packages/next/src/client/components/segment-cache/lru.ts` | LRUキャッシュ実装 |

#### Step 4: スケジューラとナビゲーション統合を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | scheduler.ts | `packages/next/src/client/components/segment-cache/scheduler.ts` | プリフェッチタスクのスケジューリング、優先度管理 |
| 4-2 | navigation.ts | `packages/next/src/client/components/segment-cache/navigation.ts` | キャッシュからのナビゲーションデータ取得 |

### プログラム呼び出し階層図

```
prefetch(href, nextUrl, tree, strategy, onInvalidate)
    |
    +-- createPrefetchURL(href) .............. URL 検証
    +-- createCacheKey(url.href, nextUrl) .... キャッシュキー生成
    +-- schedulePrefetchTask() ............... スケジューラ登録
         |
         +-- pingPrefetchTask() .............. タスク実行
         |       |
         |       +-- createFetch() ........... RSC フェッチ
         |       |       +-- Tree Prefetch (全体構造)
         |       |       +-- Segment Prefetch (個別セグメント)
         |       |
         |       +-- setInCacheMap() ......... キャッシュ格納
         |
         +-- isPrefetchTaskDirty() ........... ダーティチェック
         +-- onInvalidate callback ........... 無効化通知

navigation (キャッシュ消費)
    |
    +-- getFromCacheMap() .................... キャッシュ参照
    +-- isValueExpired() ..................... 有効期限チェック
```

### データフロー図

```
[入力]                        [処理]                          [出力]

href + nextUrl ---------> prefetch() --------> CacheKey
                           |
FlightRouterState -------> scheduler --------> PrefetchTask
                           |
RSC Server Response -----> cache.ts ---------> CacheMap (in-memory)
                           |
Navigation Request ------> navigation.ts ----> FlightRouterState (キャッシュ済み)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| prefetch.ts | `packages/next/src/client/components/segment-cache/prefetch.ts` | ソース | プリフェッチエントリーポイント（48行） |
| cache.ts | `packages/next/src/client/components/segment-cache/cache.ts` | ソース | メインキャッシュ実装 |
| cache-map.ts | `packages/next/src/client/components/segment-cache/cache-map.ts` | ソース | CacheMap CRUD |
| cache-key.ts | `packages/next/src/client/components/segment-cache/cache-key.ts` | ソース | キャッシュキー生成 |
| scheduler.ts | `packages/next/src/client/components/segment-cache/scheduler.ts` | ソース | タスクスケジューラ |
| navigation.ts | `packages/next/src/client/components/segment-cache/navigation.ts` | ソース | ナビゲーション統合 |
| lru.ts | `packages/next/src/client/components/segment-cache/lru.ts` | ソース | LRUキャッシュ |
| types.ts | `packages/next/src/client/components/segment-cache/types.ts` | ソース | 型定義 |
| vary-path.ts | `packages/next/src/client/components/segment-cache/vary-path.ts` | ソース | VaryPath管理 |
| bfcache.ts | `packages/next/src/client/components/segment-cache/bfcache.ts` | ソース | BFCache統合 |
| optimistic-routes.ts | `packages/next/src/client/components/segment-cache/optimistic-routes.ts` | ソース | 楽観的ルート |
| segment-value-encoding.ts | `packages/next/src/shared/lib/segment-cache/segment-value-encoding.ts` | ソース | セグメントキーエンコーディング（95行） |
| vary-params-decoding.ts | `packages/next/src/shared/lib/segment-cache/vary-params-decoding.ts` | ソース | VaryParamsデコーディング |
