👅
Next.js App Router クライアントキャッシュライブラリいる?
App RouterにてTanStack Queryみたいなクライアントキャッシュ必要なのかなと思い頭を整理する
Next.js のキャッシュの種類と役割
Mechanism What Where Purpose Duration Request Memoization API レスポンスなど Server React Component tree におけるデータの再利用 リクエストごと Data Cache API レスポンスなど Server ユーザーやデプロイをまたぐデータの再利用 永続的(revalidate 可) Full Route Cache HTML や RSC payload Server レンダリングコストの最適化 永続的(revalidate 可) Router Cache RSC Payload Client ナビゲーションごとのリクエスト削減 ユーザーセッション・時間(revalidate 可)
これに保存場所とスケーリング時の考慮を追記
✅ Next.js App Router における4層キャッシュまとめ(保存場所・スケーリング考慮つき)
名称 | スコープ | 目的 | 永続性 | 保存場所 | スケール時の注意点 |
---|---|---|---|---|---|
Request Memoization | 同一リクエスト内 | 重複 fetch の抑制 | リクエスト単位 | メモリ(実行プロセス内) | インスタンスごとに分離されるため、並列リクエスト間ではキャッシュされない |
Data Cache | サーバー全体(Edge等) | データ取得コストの削減 | revalidate 可能 | ファイル or CDN Edge(Vercel) | Vercel以外では自前で永続ストレージ(例:Redis, FS)構築が必要 |
Full Route Cache | サーバールート単位 | ページ全体の再レンダリング抑制 | revalidate 可能 | HTML/RSC ファイル(Edge CDN), 自前の場合サーバごとのためCDN構築必要 | ビルド時に生成・保存。Vercelならスケールに強いが、更新タイミングに注意(ISR戦略必須) |
Router Cache | クライアント側 | クライアント遷移時の再リクエスト防止 | 一時的(セッション中) | ブラウザのメモリ | ページリロードや別タブで失効。サーバーとは独立のため、スケールには影響しない |
use cache ディレクティブ
簡単で強力な印象の use cache
Directives: use cache
保存場所は・・・公式見つけられなかったけどDynamic IOの成り立ちと"use cache"の深層によるとサーバのインメモリって書いてある。これも自前の場合はキャッシュの共有には注意が必要。
Page Router 時代に重宝していた Tanstack Query は不要?
必要シーンがあるか、Page Router時代にTanStack Queryで表現していたことを App Router でも表現できるか書き出す
※ 書き出した結果比べるものじゃなかった(強引に結びつけ)
✅ TanStack Query と App Router の機能比較
機能・目的 | TanStack Query の対応 | App Router の対応例 | 備考 |
---|---|---|---|
クライアントキャッシュ | ◯ | △(基本的になし) | Client 側での状態保持が必要な場合は有効 |
サーバーキャッシュ | ✕ | ◯(use cache , revalidate ) |
静的データ・共通リソースに適している |
ローディング・エラー状態管理 | ◯(isPending, isLoading, isFetching, error など豊富な状態管理が可能) | △(Suspense , error.js ) |
App Router でも可能だが、状態の種類や制御粒度は TanStack Query に劣る |
データの再取得(Refetch) | ◯ | △(タグ付き revalidate で代替可能) | クライアント起点の再取得には TanStack Query が柔軟 |
キャッシュ制御(staleTime 等) | ◯ | △(revalidateTag による手動無効化は可能) |
時間ベースの自動無効化には非対応 |
ユーザー入力に応じた動的フェッチ | ◯ | ✕(Client Component で別途対応が必要) | クライアント完結の用途では有用 |
TanStack Query の出番はこんな時
クライアントでフェッチ/リフェッチする機会は減ったがTanStack Query が 「完全に不要」では無さそうなことがわかった。
以下のようなケースでは、むしろ積極的に使うべき
-
ユーザー入力による動的データ取得がある(検索、絞り込みなど)
-
状態付き UI のためにローディング/エラー状態を明示管理したい
-
SSR 後にクライアント側で柔軟に再取得や更新を行いたい
Discussion