shwldshwld11 days ago

一覧UIは summary と detail の取得を二段階に分離する

一覧画面で必要な最小情報だけを先に取り、行の展開や詳細遷移時だけ full detail を別クエリで取得する構成に変えた。これで初回描画時の overfetch を抑えつつ、詳細表示の責務も分離できた。

構成は次の2段階に分ける:

  1. 一覧クエリは常に detail=summary — リスト描画に必要なフィールドだけを取得する。
  2. 詳細クエリは id 単位で遅延取得 — 行展開や詳細表示のタイミングで別取得する。
// list side
query.set("detail", "summary");

// detail side
const query = useQuery({
  queryKey: itemQueryKeys.itemDetail(projectId, itemId),
  queryFn: () => fetchItemDetail(projectId, itemId),
  staleTime: 60_000,
});

この分離で効いたポイントは3つ:

  1. キャッシュ粒度が明確になる — 一覧と詳細で query key を分けると、どちらを invalidate すべきか判断しやすい。
  2. UIの責務と通信の責務が揃う — 「パネルは概要」「展開時に詳細」という画面の意図が、そのままデータ取得設計になる。
  3. 将来のフィールド追加に強い — 詳細にだけ重い関連を足しても、一覧の初期体験に影響しにくい。

今回やったこと(実施済み)

  • 一覧クエリ生成ロジックに detail=summary を追加した
  • API 入力に detailLevel を導入して usecase から repository まで伝搬した
  • 詳細取得フックを追加し、展開時に詳細を個別取得するようにした
  • 関連テストを更新して新しい取得経路を検証した

次に試す(任意)

  • summary/detail で実レスポンスサイズと描画時間を計測し、分離効果を定量化する