# 機能設計書 24-onRenderTracked() / onRenderTriggered()

## 概要

本ドキュメントは、Vue 3の`onRenderTracked()`および`onRenderTriggered()`デバッグ用ライフサイクルフックの機能設計を記述する。コンポーネントのレンダリングエフェクトが依存するリアクティブデータの追跡・トリガー情報を提供するフックであり、開発モードでのみ有効となる。

### 本機能の処理概要

`onRenderTracked()`はコンポーネントのレンダリング処理中にリアクティブな依存関係が追跡（track）されたとき、`onRenderTriggered()`はリアクティブな依存関係の変更によりレンダリングが再トリガーされたときに呼び出されるデバッグフックである。

**業務上の目的・背景**：Vueアプリケーション開発において、コンポーネントが予期しない再レンダリングを行う原因の特定が困難な場合がある。これらのフックはリアクティブ依存関係のトラッキング情報とトリガー情報をDebuggerEvent形式で提供し、パフォーマンスのボトルネックやバグの原因を効率的に特定するために使用される。

**機能の利用シーン**：コンポーネントの不要な再レンダリング原因の調査、リアクティブ依存関係の可視化、パフォーマンスデバッグ、Vue DevToolsと連携したデバッグ。

**主要な処理内容**：
1. `onRenderTracked(hook)`でデバッグフックを`LifecycleHooks.RENDER_TRACKED`（内部キー`rtc`）として登録
2. `onRenderTriggered(hook)`でデバッグフックを`LifecycleHooks.RENDER_TRIGGERED`（内部キー`rtg`）として登録
3. レンダラーの`setupRenderEffect`内でReactiveEffectの`onTrack`/`onTrigger`コールバックにフックを接続（開発モードのみ）
4. リアクティブシステムのtrack/trigger操作時にDebuggerEventを引数としてフックを呼び出し

**関連システム・外部連携**：`@vue/reactivity`パッケージ（ReactiveEffectのonTrack/onTriggerコールバック）、Vue DevTools（デバッグ情報の連携）と連携する。

**権限による制御**：権限による制御は存在しない。**開発モード（`__DEV__`）でのみ有効**であり、本番ビルドではコードがツリーシェイキングにより除去される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに直接の関連画面なし。開発モードでの任意のコンポーネントデバッグに使用される |

## 機能種別

ライフサイクルフック登録 / デバッグ・診断

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| hook | DebuggerHook (= (e: DebuggerEvent) => void) | Yes | 追跡/トリガー時に実行されるデバッグコールバック | なし |
| target | ComponentInternalInstance \| null | No | フックを登録する対象コンポーネントインスタンス（省略時はcurrentInstance） | なし |

### 入力データソース

Composition APIのsetup()関数内からのプログラム呼び出し。DebuggerEventオブジェクトはリアクティブシステムから提供される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| void | void | 戻り値なし。副作用としてコンポーネントインスタンスにフック関数を登録する |

### 出力先

コンポーネントインスタンス内部の`rtc`（render tracked hooks配列）または`rtg`（render triggered hooks配列）プロパティ。

## 処理フロー

### 処理シーケンス

```
1. onRenderTracked(hook) / onRenderTriggered(hook) 呼び出し
   └─ createHook(RENDER_TRACKED/RENDER_TRIGGERED) で生成された関数を実行
2. injectHook(type, hook, target) でフック登録
   └─ target.rtc[] / target.rtg[] にラッパー関数を追加
3. レンダラーのsetupRenderEffect内（__DEV__のみ）
   └─ effect.onTrack = instance.rtc ? e => invokeArrayFns(instance.rtc!, e) : void 0
   └─ effect.onTrigger = instance.rtg ? e => invokeArrayFns(instance.rtg!, e) : void 0
4. リアクティブシステムのtrack操作時
   └─ effect.onTrack(debuggerEvent) が呼ばれ、rtcフックが実行
5. リアクティブシステムのtrigger操作時
   └─ effect.onTrigger(debuggerEvent) が呼ばれ、rtgフックが実行
```

### フローチャート

```mermaid
flowchart TD
    A[onRenderTracked/onRenderTriggered呼び出し] --> B{__DEV__モード?}
    B -->|Yes| C[injectHookでフック登録]
    B -->|No| D[SSRチェックにより登録スキップ]
    C --> E[instance.rtc/rtg配列に追加]
    E --> F[setupRenderEffect]
    F --> G{instance.rtc/rtg存在?}
    G -->|Yes| H[effect.onTrack/onTriggerにコールバック設定]
    G -->|No| I[void 0を設定]
    H --> J[リアクティブ操作時にDebuggerEvent付きで呼び出し]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-24-01 | 開発モード限定 | レンダラーでのonTrack/onTrigger接続は`__DEV__`ブロック内でのみ行われる | レンダリングエフェクト設定時 |
| BR-24-02 | DebuggerEvent引数 | フックにはリアクティブシステムのDebuggerEvent（effect, target, type, key等）が引数として渡される | track/trigger操作時 |
| BR-24-03 | SSR時スキップ | SSRコンポーネントセットアップ中はフック登録がスキップされる（createHookのisInSSRComponentSetupチェック） | SSR時 |
| BR-24-04 | 全フック呼び出し | invokeArrayFnsにより登録された全フックが順次呼び出される | track/trigger操作時 |

### 計算ロジック

該当なし。

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

### 操作別データベース影響一覧

該当なし（クライアントサイドフレームワーク機能）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 開発警告 | setup()関数外でフックを呼び出した場合 | activeなコンポーネントインスタンスが存在しない旨の警告を出力 |
| RENDER_TRACKED / RENDER_TRIGGERED | ランタイムエラー | フック関数内で例外が発生した場合 | callWithAsyncErrorHandlingによりキャッチ |

### リトライ仕様

リトライ機構は存在しない。

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

該当なし。

## パフォーマンス要件

- **開発モード限定**のため、本番環境のパフォーマンスに影響しない
- 開発モードではリアクティブ操作ごとにコールバックが呼ばれるため、フック内での重い処理は避けるべき

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

該当なし。開発モードでのみ使用されるデバッグ機能である。

## 備考

- `onRenderTracked`は`LifecycleHooks.RENDER_TRACKED`（内部キー: `'rtc'`）に対応
- `onRenderTriggered`は`LifecycleHooks.RENDER_TRIGGERED`（内部キー: `'rtg'`）に対応
- DebuggerEventは`@vue/reactivity`パッケージからインポートされる型
- 本番ビルドでは`__DEV__`条件によりツリーシェイキングで除去されるため、バンドルサイズに影響しない

---

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

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

### 推奨読解順序

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

DebuggerHook型とライフサイクル列挙型を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | apiLifecycle.ts | `packages/runtime-core/src/apiLifecycle.ts` | `DebuggerHook`型（99行目）。`(e: DebuggerEvent) => void`型 |
| 1-2 | enums.ts | `packages/runtime-core/src/enums.ts` | `RENDER_TRIGGERED = 'rtg'`、`RENDER_TRACKED = 'rtc'` |

**読解のコツ**: `DebuggerEvent`は`@vue/reactivity`パッケージからインポートされており、`effect`, `target`, `type`, `key`等のプロパティを持つ。リアクティブ操作の詳細情報を含んでいる。

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

`onRenderTracked`/`onRenderTriggered`の定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | apiLifecycle.ts | `packages/runtime-core/src/apiLifecycle.ts` | `onRenderTriggered`（100-101行目）、`onRenderTracked`（102-103行目）。いずれも`createHook`で生成 |

**主要処理フロー**:
1. **100-101行目**: `onRenderTriggered`は`createHook<DebuggerHook>(LifecycleHooks.RENDER_TRIGGERED)`で生成
2. **102-103行目**: `onRenderTracked`は`createHook<DebuggerHook>(LifecycleHooks.RENDER_TRACKED)`で生成
3. **66-79行目**: `createHook`内でSSRチェック後に`injectHook`を呼び出し

#### Step 3: レンダラーでの接続を理解する

レンダラーのsetupRenderEffect内でReactiveEffectにフックを接続する仕組みを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | renderer.ts | `packages/runtime-core/src/renderer.ts` | `setupRenderEffect`内のonTrack/onTrigger設定（1609-1616行目） |

**主要処理フロー**:
- **1596行目**: `const effect = new ReactiveEffect(componentUpdateFn)`でレンダリングエフェクトを生成
- **1609-1612行目**: `__DEV__`ブロック内で`effect.onTrack = instance.rtc ? e => invokeArrayFns(instance.rtc!, e) : void 0`
- **1613-1615行目**: `effect.onTrigger = instance.rtg ? e => invokeArrayFns(instance.rtg!, e) : void 0`

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

```
onRenderTracked(hook) / onRenderTriggered(hook)
    │
    └─ createHook(RENDER_TRACKED / RENDER_TRIGGERED)
           │
           ├─ isInSSRComponentSetup チェック
           │
           └─ injectHook(type, hook, target)
                  └─ target.rtc[] / target.rtg[] にフック追加

[レンダラー - setupRenderEffect]（__DEV__のみ）
ReactiveEffect(componentUpdateFn)
    │
    ├─ effect.onTrack = instance.rtc ? e => invokeArrayFns(instance.rtc!, e) : void 0
    │
    └─ effect.onTrigger = instance.rtg ? e => invokeArrayFns(instance.rtg!, e) : void 0

[リアクティブ操作時]
track() → effect.onTrack(DebuggerEvent) → instance.rtc[]実行
trigger() → effect.onTrigger(DebuggerEvent) → instance.rtg[]実行
```

### データフロー図

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

hook (DebuggerHook) ───▶ createHook / injectHook    ───▶ instance.rtc[] / instance.rtg[]

[リアクティブ操作時]
DebuggerEvent       ───▶ effect.onTrack/onTrigger   ───▶ invokeArrayFns(hooks, event)
                              │                          │
                              └─ 開発モードのみ            └─ デバッグ情報出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| apiLifecycle.ts | `packages/runtime-core/src/apiLifecycle.ts` | ソース | onRenderTracked/onRenderTriggered定義、DebuggerHook型 |
| enums.ts | `packages/runtime-core/src/enums.ts` | ソース | RENDER_TRACKED/RENDER_TRIGGERED列挙値 |
| renderer.ts | `packages/runtime-core/src/renderer.ts` | ソース | setupRenderEffect内のonTrack/onTrigger設定 |
| reactivity (外部) | `packages/reactivity/src/` | ソース | ReactiveEffectクラス、DebuggerEvent型、track/trigger関数 |
