Next.jsのキャッシュでTTFB減らす!unstable_cacheとrevalidateTagの使い方
最新のNext.js 14系での効率的なデータ取得とキャッシングについて調査しました。
unstable_cache を使ったデータのキャッシュ
unstable_cache
は、高コストな操作(例: データベースクエリ)の結果をキャッシュし、複数のリクエストで再利用できるようにします。
unstable_cache の使用例
次の使用例では、キャッシュされた投稿詳細データを取得してコンポーネントで受け取っています。
キャッシュされるので取得が早くなり、TTFBが減りパフォーマンスが良くなります。
// data.js
import { getUser } from './data';
import { unstable_cache } from 'next/cache';
const getCachedPost = unstable_cache(
async (id) => getPost(id), // <= 投稿データ取得
['my-app-user'], // <= 任意のタグ
);
// PostDetailComponent.js
export default async function PostDetailComponent({ userID }) {
const user = await getCachedUser(userID);
// ... 投稿データを利用したコンポーネントのロジック
}
Next.js v14から追加された最新の機能なので、今後APIの構造が多少調整される可能性は高いとのことです。
Next.jsはApp Router導入以降、fetchを拡張する方針をとってきましたが、ユーザーやコミュニティのフィードバックを受けてその方針からの脱却を考えているとのことなので、今後unstable_cacheの活用場面は増えていくと思われます。
unstable_cache 関数のパラメータ
fetchData: キャッシュしたいデータを取得する非同期関数。Promiseを返す必要があります。
keyParts: キャッシュキーを識別するための配列。グローバルに一意な値を含む必要があります。
options: キャッシュの動作を制御するオブジェクト。
tags
(キャッシュの無効化を制御するためのタグの配列)などのプロパティを含むことができます。
revalidateTag
でタグを使用したキャッシュの無効化
revalidateTag
は特定のキャッシュタグに対してオンデマンドでキャッシュデータを削除するためのものです。
次の例では、投稿を更新するタイミングでキャッシュの再検証しています。
'use server'
import { revalidateTag } from 'next/cache'
export default async function submit() {
await UpdatePost()
// キャッシュの再検証
revalidateTag('posts')
}
注意: revalidateTag はパスが次に訪れたときにのみキャッシュを無効にします。これにより、動的なルートセグメントで revalidateTag を呼び出しても、すぐに多くの再検証がトリガーされません。再検証はパスが次に訪れたときにのみ発生します。
fetch のオプションでのタグ設定
Next.js 13.4 以降、fetch のオプションに tags
を指定可能になっています。すべての fetch の実行に対して tags
を指定しておきます。
// fetchにtagを指定する例
await fetch("http://localhost:3000/api?q", {
next: { tags: ["top-page"] },
});
// キャッシュの再検証
revalidateTag('top-page')