Next.jsのキャッシュについて

Next.jsのキャッシュについて

Yuki
Yuki

Next.jsのキャッシュについて

こんにちは。今回は、難しいけどいつかは理解しないとなーと思っているNext.jsのキャッシュについて詳しく解説します。 いっぱい書くと嫌になると思うので今回は少なく最小限に説明していこうと思います! もっと詳しく知りたいよーって方は公式ドキュメントを見てください!!

Next.jsはReactのフレームワークで、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)をサポートしています。これらの機能は、ページのロード時間を短縮し、ユーザーエクスペリエンスを向上させるために重要です。しかし、これらの機能を最大限に活用するためには、キャッシュの理解が必要です。詳細については、Next.jsの公式ドキュメントを参照してください。

Next.jsのキャッシュの基本

Next.jsでは、デフォルトで静的レンダリングが行われます。これは、ビルド時にページが事前にレンダリングされ、その結果がキャッシュされるということです。このため、ビルド後にデータを更新しても、新しいデータが表示されるまでには再ビルドが必要です。この静的レンダリングのメリットは、一度レンダリングされたページはすぐに表示できるため、ユーザーは待ち時間なくコンテンツを閲覧できます。しかし、デメリットとしては、データが更新されてもすぐに反映されないという点があります。

しかし、最新のデータをリアルタイムに表示したい場合もあります。そのような場合には、cookies()headers()noStore()などの動的レンダリングを有効にする方法を採用します。これにより、リクエストのたびに最新のデータが取得され、ページが動的にレンダリングされます。この動的レンダリングのメリットは、常に最新のデータを表示できるという点です。しかし、デメリットとしては、リクエストのたびにデータを取得しレンダリングするため、ページの表示に時間がかかる可能性があります。

静的なfetchと動的なfetch

Next.jsでは、データの取得にはfetch関数を使用します。このfetch関数は、ビルド時に一度だけデータを取得し、その結果をキャッシュします。そのため、ビルド後にデータが更新されても、新しいデータが表示されるまでには再ビルドが必要です。この静的なfetchのメリットは、一度取得したデータはすぐに使用できるため、ユーザーは待ち時間なくコンテンツを閲覧できます。しかし、デメリットとしては、データが更新されてもすぐに反映されないという点があります。詳細については、Next.jsの公式ドキュメントのData Fetching, Caching, and Revalidatingページを参照してください。

一方、リクエストのたびに最新のデータを取得したい場合には、動的なfetchを使用します。これは、cookies()headers()noStore()などの動的レンダリングを有効にする方法を採用することで実現できます。この動的なfetchのメリットは、常に最新のデータを表示できるという点です。しかし、デメリットとしては、リクエストのたびにデータを取得するため、ページの表示に時間がかかる可能性があります。

unstable_cacheの活用

Next.js v14からは、unstable_cacheという新しいキャッシュ機能が追加されました。このunstable_cacheを使用すると、ビルド時に一度だけデータを取得し、その結果をキャッシュすることができます。また、revalidateを指定することで、任意のタイミングでの再検証や時間による再検証(ISR)も実現できます。

const getCachedUser = unstable_cache(
async (id) => getUser(id),
[user-${id}],
{
tags: [user-${id}],
revalidate: 60,
}
);

このunstable_cacheはNext.js v14から追加された最新の機能で、今後APIの構造が多少調整される可能性があります。しかし、この機能により、直接DBにリクエストするユースケースでもキャッシュやその再検証を実装することが可能になりました。詳細については、Next.jsの公式ドキュメントのCaching in Next.jsページを参照してください。

キャッシュの再検証

Next.jsでは、データの更新後にキャッシュを再検証するためのいくつかの方法が提供されています。例えば、Server Actionsでデータを更新した後にrevalidateTag()またはrevalidatePath()を実行することで、キャッシュを破棄することができます。


'use server'

import { revalidateTag } from 'next/cache'

export async function createPost() {
try {
// ...
} catch (error) {
// ...
}

revalidateTag('posts');
}

また、CMSなどの外部システムからの操作(例えば記事更新など)によりデータに変更が加えられた場合は、Route HandlersによりWebhookを実装することが推奨されています。


export async function POST() {
// ...

revalidateTag('posts');

return new Response('Success!');
}

まとめ

Next.jsのキャッシュは、ページのロード時間を短縮し、ユーザーエクスペリエンスを向上させるために重要な機能です。静的レンダリングから動的レンダリング、そして最新のunstable_cacheまで、Next.jsはさまざまなキャッシュ戦略を提供しています。これらの機能を理解し、適切に活用することで、Next.jsを最大限に活用することができます。詳細については、Next.jsの公式ドキュメントのCaching in Next.jsページを参照してください。