キャッシングと再検証
キャッシングは、データ取得やその他の計算結果を保存し、同じデータへの今後のリクエストを再度計算することなく高速に処理できるようにする技術です。再検証により、アプリケーション全体を再構築することなく、キャッシュエントリを更新できます。
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をキャッシュします。ルートが動的であることを保証したい場合は、connectionAPIを使用してください。
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 { unstable_cache } from 'next/cache'
import { getUserById } from '@/app/lib/data'
export default async function Page({
params,
}: {
params: Promise<{ userId: string }>
}) {
const { userId } = await params
const getCachedUser = unstable_cache(
async () => {
return getUserById(userId)
},
[userId] // キャッシュキーにユーザーIDを追加
)
}この関数は、キャッシュをどのように再検証するかを定義する、3番目のオプションのオブジェクトを受け入れます。以下のオプションを受け入れます:
tags:Next.jsがキャッシュを再検証するために使用するタグの配列。revalidate:キャッシュを再検証するまでの秒数。
const getCachedUser = unstable_cache(
async () => {
return getUserById(userId)
},
[userId],
{
tags: ['user'],
revalidate: 3600,
}
)詳細は、unstable_cache APIリファレンスをご覧ください。
revalidateTag
revalidateTagは、タグに基づくキャッシュエントリを再検証し、イベント後に実行するために使用されます。この関数は現在、2つの動作をサポートしています:
profile="max"付き:stale-while-revalidateセマンティクスを使用し、バックグラウンドで新しいコンテンツを取得中に古いコンテンツを提供します- 2番目の引数なし:キャッシュを直ちに期限切れにする従来の動作(非推奨)
fetchで使用するには、next.tagsオプションで関数にタグを付けることから始めてください:
export async function getUserById(id: string) {
const data = await fetch(`https://...`, {
next: {
tags: ['user'],
},
})
}または、tagsオプションでunstable_cache関数にマークを付けることができます:
export const getUserById = unstable_cache(
async (id: string) => {
return db.query.users.findFirst({ where: eq(users.id, id) })
},
['user'], // 変数がパラメータとして渡されていない場合は必須
{
tags: ['user'],
}
)次に、ルートハンドラーまたはServer ActionでrevalidateTagを呼び出します:
import { revalidateTag } from 'next/cache'
export async function updateUser(id: string) {
// データを変更
revalidateTag('user', 'max') // 推奨:stale-while-revalidateを使用
}複数の関数で同じタグを再利用し、すべてを一度に再検証できます。
詳細は、revalidateTag APIリファレンスをご覧ください。
revalidatePath
revalidatePathは、ルートを再検証し、イベント後に実行するために使用されます。これを使用するには、ルートハンドラーまたはServer Actionで呼び出してください:
import { revalidatePath } from 'next/cache'
export async function updateUser(id: string) {
// データを変更
revalidatePath('/profile')詳細は、revalidatePath APIリファレンスをご覧ください。
updateTag
updateTagは、Server Actionで読み取り後の自分の書き込みシナリオ用にキャッシュデータを直ちに期限切れにするように特に設計されています。revalidateTagとは異なり、Server Action内でのみ使用でき、キャッシュエントリを直ちに期限切れにします。
import { updateTag } from 'next/cache'
import { redirect } from 'next/navigation'
export async function createPost(formData: FormData) {
// データベースにポストを作成
const post = await db.post.create({
data: {
title: formData.get('title'),
content: formData.get('content'),
},
})
// キャッシュを直ちに期限切れにして、新しいポストが表示されるようにする
updateTag('posts')
updateTag(`post-${post.id}`)
redirect(`/posts/${post.id}`)
}revalidateTagとupdateTagの主な違い:
updateTag:Server Actionのみで使用可能、キャッシュを直ちに期限切れにする、読み取り後の自分の書き込み用revalidateTag:Server ActionおよびRoute Handlerで使用可能、profile="max"でstale-while-revalidateをサポート
詳細は、updateTag APIリファレンスをご覧ください。