Menu

use cache

use cache ディレクティブを使用すると、ルート、React コンポーネント、または関数をキャッシュ可能としてマークできます。ファイルの最上部で使用すると、ファイル内のすべてのエクスポートがキャッシュされることを示します。また、関数またはコンポーネントの最上部にインラインで使用して、戻り値をキャッシュできます。

補足: Cookie やヘッダーへのアクセスが必要なユーザー固有のコンテンツをキャッシュする場合は、'use cache: private' を参照してください。

使用方法

use cache は Cache Components 機能です。これを有効にするには、next.config.ts ファイルに cacheComponents オプションを追加してください。

next.config.ts
TypeScript
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  cacheComponents: true,
}
 
export default nextConfig

次に、ファイル、コンポーネント、または関数レベルで use cache を追加します。

// ファイルレベル
'use cache'
 
export default async function Page() {
  // ...
}
 
// コンポーネントレベル
export async function MyComponent() {
  'use cache'
  return <></>
}
 
// 関数レベル
export async function getData() {
  'use cache'
  const data = await fetch('/api/data')
  return data
}

use cache の仕組み

キャッシュキー

キャッシュエントリのキーは、入力のシリアライズ版を使用して生成され、以下を含みます。

  • ビルド ID(各ビルドで生成される)
  • 関数 ID(関数に一意のセキュアな識別子)
  • シリアライズ可能な関数の引数(またはプロパティ)

キャッシュされた関数に渡される引数、および親スコープから読み込まれる値は、自動的にキーの一部になります。つまり、入力が同じである限り、同じキャッシュエントリが再利用されます。

シリアライズ不可能な引数

シリアライズ不可能な引数、プロパティ、またはクロージャ値は、キャッシュされた関数内の参照に変わり、渡すことのみができ、検査および変更はできません。これらのシリアライズ不可能な値はリクエスト時に入力され、キャッシュキーの一部にはなりません。

たとえば、キャッシュされた関数は JSX を children プロパティとして受け取り、<div>{children}</div> を返すことができますが、実際の children オブジェクトを検査することはできません。これにより、キャッシュされていないコンテンツをキャッシュされたコンポーネント内にネストできます。

app/ui/cached-component.tsx
TypeScript
function CachedComponent({ children }: { children: ReactNode }) {
  'use cache'
  return <div>{children}</div>
}

戻り値

キャッシュ可能な関数の戻り値はシリアライズ可能である必要があります。これにより、キャッシュされたデータを正しく保存および取得できることが保証されます。

ビルド時の use cache

レイアウトまたはページの最上部で使用する場合、ルートセグメントは事前レンダリングされ、後で再検証できるようになります。

これは、use cachecookies または headers などのランタイムデータと一緒に使用できないことを意味します。

注意: Cookie、ヘッダー、または検索パラメータに依存するコンテンツをキャッシュする必要がある場合は、代わりに 'use cache: private' を使用してください。

ランタイムでの use cache

サーバー上では、個々のコンポーネントまたは関数のキャッシュエントリがメモリ内にキャッシュされます。

その後、クライアント上では、サーバーキャッシュから返されたコンテンツがブラウザのメモリに保存され、セッションの期間中、または再検証されるまで保持されます。

再検証時

デフォルトでは、use cache のサーバー側再検証期間は 15 分です。この期間は、頻繁な更新が不要なコンテンツに役立つ場合がありますが、cacheLifecacheTag API を使用して、個々のキャッシュエントリをいつ再検証するかを設定できます。

  • cacheLife:キャッシュエントリの有効期間を設定します。
  • cacheTag:オンデマンド再検証用のタグを作成します。

これらの API は両方ともクライアント側とサーバー側のキャッシング層全体に統合されているため、1 つの場所でキャッシング意味論を設定し、それらをすべての場所に適用できます。

詳細については、cacheLife および cacheTag API ドキュメントを参照してください。

use cache を使用したルート全体のキャッシング

ルート全体を事前レンダリングするには、layout ファイルと page ファイルの両方の最上部に use cache を追加します。これらの各セグメントは、アプリケーション内の個別のエントリポイントとして扱われ、独立してキャッシュされます。

app/layout.tsx
TypeScript
'use cache'
 
export default function Layout({ children }: { children: ReactNode }) {
  return <div>{children}</div>
}

page ファイルでインポートおよびネストされるすべてのコンポーネントは、page に関連するキャッシュ出力の一部です。

app/page.tsx
TypeScript
'use cache'
 
async function Users() {
  const users = await fetch('/api/users')
  // ユーザーをループする
}
 
export default function Page() {
  return (
    <main>
      <Users />
    </main>
  )
}

補足:

  • use cachelayout または page のみに追加されている場合は、そのルートセグメントとそれにインポートされるコンポーネントのみがキャッシュされます。
  • ルート内のネストされた子のいずれかが動的 API を使用する場合、ルートは事前レンダリングから除外されます。

use cache でコンポーネント出力をキャッシングする

コンポーネントレベルで use cache を使用して、そのコンポーネント内で実行されるフェッチまたは計算をキャッシュできます。キャッシュエントリは、シリアライズされたプロパティが各インスタンスで同じ値を生成する限り再利用されます。

app/components/bookings.tsx
TypeScript
export async function Bookings({ type = 'haircut' }: BookingsProps) {
  'use cache'
  async function getBookingsData() {
    const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
    return data
  }
  return //...
}
 
interface BookingsProps {
  type: string
}

use cache で関数出力をキャッシングする

use cache を任意の非同期関数に追加できるため、コンポーネントまたはルートのキャッシングに限定されません。ネットワークリクエスト、データベースクエリ、または低速な計算をキャッシュしたい場合があります。

app/actions.ts
TypeScript
export async function getData() {
  'use cache'
 
  const data = await fetch('/api/data')
  return data
}

インターリーブ

React では、children またはスロットを使用した合成は、柔軟なコンポーネントを構築するための周知のパターンです。use cache を使用する場合、このようにして UI を合成し続けることができます。返される JSX に children またはその他の合成スロットとして含められるものはすべて、キャッシュエントリに影響を与えることなく、キャッシュされたコンポーネントを通じて渡されます。

キャッシュ可能な関数本体内の JSX スロットを直接参照しない限り、返された出力にそれらが存在してもキャッシュエントリに影響を与えません。

app/page.tsx
TypeScript
export default async function Page() {
  const uncachedData = await getData()
  return (
    // 合成スロットをプロパティとして渡す(例:ヘッダーと children)
    <CacheComponent header={<h1>Home</h1>}>
      {/* DynamicComponent が children スロットとして提供される */}
      <DynamicComponent data={uncachedData} />
    </CacheComponent>
  )
}
 
async function CacheComponent({
  header, // header:合成スロット、プロパティとして注入
  children, // children:ネストされた合成用の別のスロット
}: {
  header: ReactNode
  children: ReactNode
}) {
  'use cache'
  const cachedData = await fetch('/api/cached-data')
  return (
    <div>
      {header}
      <PrerenderedComponent data={cachedData} />
      {children}
    </div>
  )
}

キャッシュ可能な関数内で呼び出さずに、キャッシュされたコンポーネントを通じて Server Actions をクライアントコンポーネントに渡すこともできます。

app/page.tsx
TypeScript
import ClientComponent from './ClientComponent'
 
export default async function Page() {
  const performUpdate = async () => {
    'use server'
    // サーバー側の更新を実行する
    await db.update(...)
  }
 
  return <CacheComponent performUpdate={performUpdate} />
}
 
async function CachedComponent({
  performUpdate,
}: {
  performUpdate: () => Promise<void>
}) {
  'use cache'
  // ここで performUpdate を呼び出さないでください
  return <ClientComponent action={performUpdate} />
}
app/ClientComponent.tsx
TypeScript
'use client'
 
export default function ClientComponent({
  action,
}: {
  action: () => Promise<void>
}) {
  return <button onClick={action}>Update</button>
}

プラットフォームサポート

デプロイメントオプションサポート
Node.js サーバーはい
Docker コンテナはい
静的エクスポートいいえ
アダプタープラットフォーム固有

Next.js を自己ホストする場合のキャッシング設定方法を学びます。

バージョン履歴

バージョン変更内容
v16.0.0"use cache" は Cache Components 機能で有効になりました。
v15.0.0"use cache" は試験的機能として導入されました。