tsutsu
ホームサービスプロフィールお知らせブログお問い合わせ
tsutsu

Web開発・システム開発支援

代表:堤 暁寛

ナビゲーション

ホームサービスプロフィールお知らせブログお問い合わせ

ソーシャル

© 2026 tsutsu. All rights reserved.

  1. ブログ
  2. cacheComponentってなんやねん
cacheComponentってなんやねん
テクノロジー
2025年11月22日

cacheComponentってなんやねん

こんにちは!つつです!
この前next.jsのCache Componentsの挙動に振り回されたので、まとめます。


そもそも「キャッシュ」とは?

Web アプリの世界で「キャッシュ」とは、
一度計算したり取得した結果を保存しておき、次回以降はそれを使い回す仕組み のことです。

Cache Components って何者?

Cache Components は Next.js 15 以降で導入された新しいキャッシュモデルで、Next.js 16 世代では cacheComponents フラグで本格的に利用できます。


App Router(app/)で、

  • ページ全体を静的生成
  • 一部だけキャッシュ
  • 一部は毎回動的

みたいな「静的・キャッシュ・動的を1ルート内で混在」させやすくするための機能です。
Next.jsの公式ドキュメント

中心になるのがこのあたり

  • use cache
  • use cache: remote
  • use cache: private

💡補足:Cache Components は RSC(サーバーコンポーネント)専用
Cache Components が利用できるのは Server Component またはサーバー側の関数だけで、
"use client" を含む Client Component は対象外です。
キャッシュしたい処理は Server Component 側に寄せる必要があります。

普通のコンポーネントと何が違うの?

普通のコンポーネントは、呼ばれるたびに表示に必要な処理を毎回行いレスポンスを返す。

キャッシュコンポーネントは2回目以降に同じリクエストがきたらキャッシュされたレスポンスを返します。


どうやって有効化するの?

まず next.config.{js,ts} でフラグをオン にします:

next.ts
// next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheComponents: true,
}

export default nextConfig

これで Cache Components 機能が有効になります。


use cache の基本イメージ

ファイルレベルでキャッシュ

next.tsx
// app/page.tsx
'use cache'

export default async function Page() {
  const data = await getData()
  return <main>{data.title}</main>
}
  • ファイル先頭に "use cache" を書くと
    → そのファイルの すべてのエクスポートがキャッシュ対象 になります。

コンポーネント/関数レベルでキャッシュ

next.tsx
// コンポーネントレベル
export async function Card({ id }: { id: string }) {
  'use cache'
  const data = await getPost(id)
  return <div>{data.title}</div>
}

// 関数レベル
export async function getPost(id: string) {
  'use cache'
  const res = await fetch(`https://example.com/posts/${id}`)
  return res.json()
}
  • 同じ引数で呼ばれたときは 前回の結果を再利用
  • キーは「関数の引数」と、そのスコープから参照している値(クロージャの値)などから 自動的に生成 されます。

どこまでがキャッシュ対象?(file / component / function の違い)

キャッシュ対象の範囲は、use cache を書く場所で決まります。

書く場所

キャッシュ対象

ファイル先頭

そのファイル内のすべてのエクスポート

コンポーネント内

そのコンポーネントの戻り値

関数内

その関数の戻り値

これが分かると、「キャッシュが効くと思ったのに効かない」問題は解決しやすいと思います。


Fetch のキャッシュと Cache Components のキャッシュの違い

Next.js には少なくとも 2種類のキャッシュ があります:

種類

何をキャッシュするか

代表的な指定方法

fetch のキャッシュ

HTTP レスポンス

fetch(url, { cache, next: { revalidate } })

Cache Components

コンポーネント / 関数の戻り値

'use cache' / 'use cache: remote' / 'use cache: private'

ポイントは、この2つは完全に別レイヤー だということです。

fetch が no-store でも Cache Components はキャッシュされる

next.tsx
'use cache'

export async function getData() {
  // 毎回リクエストは飛ぶ
  const res = await fetch('https://example.com/posts', {
    cache: 'no-store',
  })
  // でも getData の「戻り値」は Cache Components によってキャッシュされる
  return res.json()
}
  • fetch は毎回 API を叩く
  • ただし getData() の戻り値はキャッシュ済みのものが再利用される

つまり:

  • 「ネットワークをキャッシュしたいか?」 → fetch の設定
  • 「コンポーネント/関数の結果をキャッシュしたいか?」 → use cache の設定

と考えると整理しやすいです。


Next.js の 3 種類のキャッシュ指示子について理解する

Next.js には 3 種類のキャッシュ指示子があります:

  • use cache(基本形)
  • use cache: remote(共有キャッシュ:外部ストア)
  • use cache: private(ユーザーごと)

それぞれの違いは、ざっくり次の 3 点です:

  • キャッシュの保存先(ローカル / 外部ストア / ユーザー専用)
  • キャッシュが共有される範囲
  • リクエスト依存情報(cookies / headers など)が使えるか

1. use cache(基本形)

もっともシンプルなキャッシュ方式。
静的コンテキスト向け。

特徴

  • 全員同じ結果を共有するキャッシュ
  • use cache を書いた関数やコンポーネントの 中では cookies() や headers() は使えません。
    一方、別コンポーネントで cookies を読み取り、その値を引数として use cache 側に渡すことは可能です。
  • 同じ引数の関数呼び出しで 結果が再利用される
  • デフォルトではサーバーのメモリ内にキャッシュされます(必要に応じて cacheHandlers でリモートキャッシュに変えることもできます)。

向いているケース

  • 公開記事一覧
  • 共通設定、定数的データ
  • 「誰が見ても同じで OK」なページ

サンプルコード

next.tsx
export async function getPublicPosts() {
  'use cache'

  const res = await fetch('https://example.com/posts')
  return res.json()
}

2. use cache: remote(共有キャッシュを外部ストアに保存)

キャッシュ結果はサーバー側のキャッシュハンドラに保存され、全ユーザーで共有されます(KV / Redis などのリモートキャッシュに置くイメージ)。

特徴

  • 全サーバー・全リージョンで共有されるキャッシュ
  • 結果は 全ユーザー共通(=ユーザー固有情報は NG)
  • どのリージョンからでも同じキャッシュを取得できる

イメージ

  • use cache: サーバー内のローカルキャッシュ
  • use cache: remote: 外部キャッシュ(Redis / KV)に保存して全体で共有

向いているケース

  • 為替レート
  • 公開統計情報
  • ランキングなど「全員同じで OK」かつ アクセス頻度が高いデータ

サンプルコード

next.tsx
export async function getExchangeRate(base: string, target: string) {
  'use cache: remote'

  const res = await fetch(
    `https://api.example.com/rate?base=${base}&target=${target}`
  )
  return res.json()
}

3. use cache: private(ユーザーごとのキャッシュ)

ログインユーザーごとにキャッシュを分離したい場合の専用モード。

特徴

  • cookies() / headers() / searchParams の使用が可能
  • 結果は そのユーザーだけのプライベートキャッシュ
  • A さんと B さんで完全に別キャッシュ → 他人のデータを誤表示しない

向いているケース

  • マイページ
  • ユーザー設定
  • カート情報
  • ダッシュボード

サンプルコード

next.tsx
import { cookies } from 'next/headers'

export async function getMyDashboardData() {
  'use cache: private'

  const session = cookies().get('session_id')?.value
  const res = await fetch('https://example.com/api/me', {
    headers: { 'x-session-id': session ?? '' },
  })
  return res.json()
}

早見表

種類

共有範囲

ユーザー依存情報

向いている用途

use cache

サーバー内 / ビルド単位

❌ 使わない前提

公開記事一覧・定数的データ

use cache: remote

全サーバー・全リージョン

❌ 使用不可

為替・ランキングのような共通データ

use cache: private

ユーザーごと

✅ 使用可能

マイページ・個別設定・カート


Cache Components はいつ更新される?(cacheLife の基本)

'use cache' だけ使った場合は、Next.js が 自動で定期的に再検証します。

より細かく制御したい場合は cacheLife()。

use cache だけを指定した場合は、Next.js が default プロファイル(stale 5分 / revalidate 15分 / expire 1年)に基づいて自動再検証します。
ただし挙動を明示したい場合は、cacheLife('hours') などでプロファイルを指定するのがおすすめです。

next.tsx
import { cacheLife } from 'next/cache'

export async function getPosts() {
  'use cache'
  cacheLife('hours') // 数時間おきに更新

  return fetch('https://example.com/posts').then(r => r.json())
}

よく使うプリセット

プリセット

意味

使うケース

seconds

数秒

株価、スポーツスコア

minutes

数分

タイムライン

hours

数時間

API 全般

days

1日1回

ブログ一覧

max

不変に近い

アーカイブ


まとめ

Next.js 16 の Cache Components は、従来よりも 細かな単位でキャッシュ戦略をコントロールできる新しい仕組み です。
ページ全体だけでなく、コンポーネントや関数レベルでキャッシュを明示できるため、
「静的」「キャッシュ」「動的」を 1 つのルートで柔軟に混在させることが可能になります!