データのキャッシュと再検証方法
キャッシュとは、データフェッチやその他の計算結果を保存する技術で、同じデータへの将来のリクエストを再度作業することなく高速に提供できるようにします。一方、再検証(revalidation)を使用すると、アプリケーション全体を再構築することなくキャッシュエントリを更新できます。
Next.jsはキャッシュと再検証を扱うためのいくつかのAPIを提供しています。このガイドでは、それらをいつ、どのように使用するかを説明します。
fetch
デフォルトでは、fetch
リクエストはキャッシュされません。cache
オプションを'force-cache'
に設定することで、個々のリクエストをキャッシュできます。
export default async function Page() {
const data = await fetch('https://...', { 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 } })
}
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])
}
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を追加
)
}
import { unstable_cache } from 'next/cache';
import { getUserById } from '@/app/lib/data';
export default async function Page({ params } }) {
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,
}
)
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'],
},
})
}
export async function getUserById(id) {
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'],
}
)
export const getUserById = unstable_cache(
async (id) => {
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')
}
import { revalidateTag } from 'next/cache'
export async function updateUser(id) {
// データを変更
revalidateTag('user')
}
同じタグを複数の関数で再利用して、一度にすべてを再検証できます。
詳細については、revalidateTag
APIリファレンスを参照してください。
revalidatePath
revalidatePath
は、イベント後にルートを再検証するために使用されます。使用するには、Route HandlerまたはServer Actionで呼び出します:
import { revalidatePath } from 'next/cache'
export async function updateUser(id: string) {
// データを変更
revalidatePath('/profile')
import { revalidatePath } from 'next/cache'
export async function updateUser(id) {
// データを変更
revalidatePath('/profile')
詳細については、revalidatePath
APIリファレンスを参照してください。