データのキャッシュと再検証方法

キャッシュとは、データフェッチやその他の計算結果を保存する技術で、同じデータへの将来のリクエストを再度作業することなく高速に提供できるようにします。一方、再検証(revalidation)を使用すると、アプリケーション全体を再構築することなくキャッシュエントリを更新できます。

Next.jsはキャッシュと再検証を扱うためのいくつかのAPIを提供しています。このガイドでは、それらをいつ、どのように使用するかを説明します。

fetch

デフォルトでは、fetchリクエストはキャッシュされません。cacheオプションを'force-cache'に設定することで、個々のリクエストをキャッシュできます。

export default async function Page() {
  const data = await fetch('https://...', { cache: 'force-cache' })
}

豆知識: fetchリクエストはデフォルトではキャッシュされませんが、Next.jsはfetchリクエストがあるルートをプリレンダリングし、HTMLをキャッシュします。ルートが動的であることを保証したい場合は、connection APIを使用してください。

fetchリクエストで返されたデータを再検証するには、next.revalidateオプションを使用できます。

export default async function Page() {
  const data = await fetch('https://...', { next: { revalidate: 3600 } })
}

これにより、指定された秒数後にデータが再検証されます。

詳細については、fetch APIリファレンスを参照してください。

unstable_cache

unstable_cacheを使用すると、データベースクエリやその他の非同期関数の結果をキャッシュできます。使用するには、関数をunstable_cacheでラップします。例:

import { db } from '@/lib/db'
export async function getUserById(id: string) {
  return db
    .select()
    .from(users)
    .where(eq(users.id, id))
    .then((res) => res[0])
}
import { db } from '@/lib/db'

export async function getUserById(id) {
  return db
    .select()
    .from(users)
    .where(eq(users.id, id))
    .then((res) => res[0])
}

この関数は、キャッシュをどのように再検証するかを定義するための第3のオプションオブジェクトを受け入れます。以下のプロパティがあります:

  • tags: Next.jsがキャッシュを再検証するために使用するタグの配列
  • revalidate: キャッシュを再検証するまでの秒数
const getCachedUser = unstable_cache(
  async () => {
    return getUserById(userId)
  },
  [userId],
  {
    tags: ['user'],
    revalidate: 3600,
  }
)

詳細については、unstable_cache APIリファレンスを参照してください。

revalidateTag

revalidateTagは、イベント後にタグに基づいてキャッシュエントリを再検証するために使用されます。fetchと一緒に使用するには、まずnext.tagsオプションで関数にタグを付けます:

export async function getUserById(id: string) {
  const data = await fetch(`https://...`, {
    next: {
      tags: ['user'],
    },
  })
}

または、unstable_cache関数にtagsオプションをマークすることもできます:

export const getUserById = unstable_cache(
  async (id: string) => {
    return db.query.users.findFirst({ where: eq(users.id, id) })
  },
  ['user'], // 変数がパラメータとして渡されない場合に必要
  {
    tags: ['user'],
  }
)

次に、Route HandlerまたはServer ActionでrevalidateTagを呼び出します:

import { revalidateTag } from 'next/cache'

export async function updateUser(id: string) {
  // データを変更
  revalidateTag('user')
}

同じタグを複数の関数で再利用して、一度にすべてを再検証できます。

詳細については、revalidateTag APIリファレンスを参照してください。

revalidatePath

revalidatePathは、イベント後にルートを再検証するために使用されます。使用するには、Route HandlerまたはServer Actionで呼び出します:

import { revalidatePath } from 'next/cache'

export async function updateUser(id: string) {
  // データを変更
  revalidatePath('/profile')

詳細については、revalidatePath APIリファレンスを参照してください。

On this page