cacheLife

cacheLife 関数は、関数やコンポーネントのキャッシュ有効期間を設定するために使用されます。use cache ディレクティブと共に、関数やコンポーネントのスコープ内で使用する必要があります。

使用方法

cacheLife を使用するには、まず next.config.js ファイルで dynamicIO フラグを有効にします:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    dynamicIO: true,
  },
}

export default nextConfig

次に、関数やコンポーネントのスコープ内で cacheLife 関数をインポートして呼び出します:

'use cache'
import { unstable_cacheLife as cacheLife } from 'next/cache'

export default async function Page() {
  cacheLife('hours')
  return <div>Page</div>
}

リファレンス

デフォルトのキャッシュプロファイル

Next.js はさまざまな時間スケールに基づいた名前付きキャッシュプロファイルを提供しています。use cache ディレクティブと共に cacheLife 関数でキャッシュプロファイルを指定しない場合、Next.js は自動的に default キャッシュプロファイルを適用します。

ただし、use cache ディレクティブを使用する際は、常にキャッシュプロファイルを追加してキャッシュ動作を明示的に定義することを推奨します。

プロファイルstalerevalidateexpire説明
default5分15分1年頻繁な更新を必要としないコンテンツに適したデフォルトプロファイル
seconds01秒1秒ほぼリアルタイムの更新を必要とする急速に変化するコンテンツ用
minutes5分1分1時間1時間以内に頻繁に更新されるコンテンツ用
hours5分1時間1日毎日更新されるが、少し古くてもよいコンテンツ用
days5分1日1週間毎週更新されるが、1日古くてもよいコンテンツ用
weeks5分1週間30日毎月更新されるが、1週間古くてもよいコンテンツ用
max5分30日1年ほとんど更新を必要としない非常に安定したコンテンツ用

キャッシュプロファイルを参照する文字列値には固有の意味はなく、セマンティックなラベルとして機能します。これにより、コードベース内でキャッシュされたコンテンツをよりよく理解し、管理できます。

豆知識: staleTimesexpireTime 設定オプションを更新すると、default キャッシュプロファイルの staleexpire プロパティも更新されます。

カスタムキャッシュプロファイル

next.config.ts ファイルの cacheLife オプションにカスタムキャッシュプロファイルを追加することで設定できます。

キャッシュプロファイルは以下のプロパティを含むオブジェクトです:

プロパティ説明要件
stalenumberクライアントがサーバーをチェックせずに値をキャッシュする期間任意
revalidatenumberサーバー上でキャッシュを更新する頻度。再検証中は古い値が提供される可能性があります任意
expirenumber値が古くなり、動的フェッチに切り替わるまでの最大期間。revalidate より長くなければなりません任意 - revalidate より長い必要があります

stale プロパティは staleTimes 設定とは異なり、クライアントサイドのルーターキャッシュを具体的に制御します。staleTimes が動的および静的データのすべてのインスタンスに影響を与えるグローバル設定であるのに対し、cacheLife 設定では関数やルートごとに「stale」時間を定義できます。

豆知識: 「stale」プロパティは Cache-control: max-age ヘッダーを設定しません。代わりにクライアントサイドのルーターキャッシュを制御します。

再利用可能なキャッシュプロファイルの定義

next.config.ts ファイルでキャッシュプロファイルを定義することで、再利用可能なキャッシュプロファイルを作成できます。ユースケースに合った名前を選択し、stalerevalidateexpire プロパティの値を設定します。必要なだけカスタムキャッシュプロファイルを作成できます。各プロファイルは、cacheLife 関数に渡される文字列値として名前で参照できます。

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    dynamicIO: true,
    cacheLife: {
      biweekly: {
        stale: 60 * 60 * 24 * 14, // 14日
        revalidate: 60 * 60 * 24, // 1日
        expire: 60 * 60 * 24 * 14, // 14日
      },
    },
  },
}

module.exports = nextConfig

上記の例では、14日間キャッシュし、毎日更新をチェックし、14日後にキャッシュを期限切れにします。その後、このプロファイルをアプリケーション全体で名前で参照できます:

app/page.tsx
'use cache'
import { unstable_cacheLife as cacheLife } from 'next/cache'

export default async function Page() {
  cacheLife('biweekly')
  return <div>Page</div>
}

デフォルトキャッシュプロファイルの上書き

デフォルトのキャッシュプロファイルは、キャッシュ可能な出力の新鮮さや古さについて考える便利な方法を提供しますが、アプリケーションのキャッシュ戦略に合わせて異なる名前付きプロファイルを好む場合があります。

デフォルトと同じ名前で新しい設定を作成することで、デフォルトの名前付きキャッシュプロファイルを上書きできます。

以下の例は、デフォルトの「days」キャッシュプロファイルを上書きする方法を示しています:

next.config.ts
const nextConfig = {
  experimental: {
    dynamicIO: true,
    cacheLife: {
      days: {
        stale: 3600, // 1時間
        revalidate: 900, // 15分
        expire: 86400, // 1日
      },
    },
  },
}

module.exports = nextConfig

インラインでのキャッシュプロファイル定義

特定のユースケースでは、cacheLife 関数にオブジェクトを渡すことでカスタムキャッシュプロファイルを設定できます:

'use cache'
import { unstable_cacheLife as cacheLife } from 'next/cache'

export default async function Page() {
  cacheLife({
    stale: 3600, // 1時間
    revalidate: 900, // 15分
    expire: 86400, // 1日
  })

  return <div>Page</div>
}

このインラインキャッシュプロファイルは、作成された関数またはファイルにのみ適用されます。同じプロファイルをアプリケーション全体で再利用したい場合は、設定を追加して next.config.ts ファイルの cacheLife プロパティに追加できます。

use cachecacheLife のネストされた使用法

同じルートやコンポーネントツリー内で複数のキャッシュ動作を定義する場合、内部キャッシュが独自の cacheLife プロファイルを指定していると、外側のキャッシュはそれらの中で最も短いキャッシュ期間を尊重します。これは、外側のキャッシュに明示的な cacheLife プロファイルが定義されていない場合にのみ適用されます。

例えば、ページに use cache ディレクティブを追加し、キャッシュプロファイルを指定しない場合、デフォルトのキャッシュプロファイルが暗黙的に適用されます(cacheLife(”default”))。ページにインポートされたコンポーネントも use cache ディレクティブと独自のキャッシュプロファイルを使用している場合、外側と内側のキャッシュプロファイルが比較され、プロファイルで設定された最短の期間が適用されます。

app/components/parent.tsx
// 親コンポーネント
import { unstable_cacheLife as cacheLife } from 'next/cache'
import { ChildComponent } from './child'

export async function ParentComponent() {
  'use cache'
  cacheLife('days')

  return (
    <div>
      <ChildComponent />
    </div>
  )
}

別のファイルで、インポートされた子コンポーネントを定義します:

app/components/child.tsx
// 子コンポーネント
import { unstable_cacheLife as cacheLife } from 'next/cache'

export async function ChildComponent() {
  'use cache'
  cacheLife('hours')
  return <div>Child Content</div>

  // このコンポーネントのキャッシュは短い「hours」プロファイルを尊重します
}