Next.js(App Router)のキャッシュ制御にオンデマンドrevalidationを利用する
Next.js(App Router)の重要な機能にfetch APIを利用した強力なDataキャッシュ機構があります。
どれぐらい強力かというと1度取得したデータは永続化されアプリケーションが再起動されても初期化されることがありません。
強力ですが使いにくいですね。永続化させない方法は色々ありますが、fetch()
に{ cache: 'no-store' }
を指定する方法が簡単です。
const response = await fetch(
`https://example.com/api/foo`,
{ cache: 'no-store' }
)
これで従来のHTTP clientと同じ感覚で開発ができるようになります。
ただ、Next.js(App Router)の魅力を引き出そうとすると、この強力なキャッシュ機構といかに向き合うのかが課題になってきます。
オンデマンドrevalidationを利用
キャッシュ制御の一つの方法としてオンデマンドrevalidationを利用する方法があります。
これはオンデマンドISRのfetch()
版でWebhookやServer Actionsを通してfetchのキャッシュをパージすることが出来ます。
オンデマンドrevalidationはpath単位でパージを行うrevalidatePathと名前空間としてタグ付けを行い、そのタグ単位でパージができるrevalidateTagがあります。
revalidateTag
を利用する場合、fetch()
時にオプションとしてtagsプロパティに配列で名前を指定します。
const response = await fetch(
`https://example.com/foo/bar`,
{
next: {
tags: ["articles"],
}
}
)
Webhookを利用してパージを行う場合は、Route Handlerを利用してエンドポイントを作成して、そこでrevalidateTag
を実行します。
import { NextResponse } from "next/server";
import { revalidateTag } from "next/cache";
export async function GET() {
revalidateTag("articles")
return NextResponse.json({ message: "revalidate articles" });
}
この指定ですとhttps://localhost:3000/xxxxx
にアクセスするとfetch()のキャッシュがパージされ最新の情報を取得できるようになります。
オンデマンドrevalidationを利用するとかなり高度なキャッシュ制御が可能になりアプリケーションのパフォーマンスを向上させる可能性を秘めています。
Discussion