Next.jsの"use cache"の概要を掴みたいあなたへ
はじめに
先日、Next.js Conf 2024が開催されました!(日本時間だと眠い時間帯でしたね...)
そこで話題になったのが"use cache"
ではないでしょうか?今回は以下のブログをもとに、"use cache"
の概要について解説していきたいと思います。"use cache"
がどんなものかを掴みたい人はぜひ最後までお読みください!
Next.js App Routerのcache
App Routerではこれまでデフォルトでcacheが有効でした。例えばfetch()
関数においてデフォルトでcacheが有効であり、開発者としては動的に取得したいのに、デフォルトが静的であるため動的なアプリケーション作成では開発体験はあまりよくありませんでした。
しかし、これからのApp Routerでは、fetch()
関数はデフォルトでcacheされません。つまり、デフォルトの状態ではすべて動的となります。
では、これからはcacheさせたいときはどうするか。そこで"use cache"
の登場です。
"use cache"
cacheを有効にしたいところに"use cache"
を定義します。
ページ全体をcacheさせる
静的なページを作成する場合などは、app/page.tsx
のファイルTOPに"use cache"
を定義することで対応できます。
"use cache"
export default async function Page() {
return fetch(...) // no error
}
部分的にcacheさせる
基本的にはデフォルトでcacheさせたいが、一部の処理を動的にしたい場合などは以下のようにします。app/layout.tsx
で"use cache"
を定義することで、基本的にはcacheを有効にさせつつ、app/page.tsx
で一部だけ動的にデータをfetchすることも可能です。
"use cache"
export default async function Layout({ children }) {
const response = await fetch(...)
const data = await response.json()
return <html>
<body>
<div>{data.notice}</div>
{children}
</body>
</html>
}
import { Suspense } from 'react'
async function Component() {
return fetch(...) // no error
}
export default async function Page() {
return <Suspense fallback="..."><Component /></Suspense>
}
「デフォルトでcacheを有効にして、一部だけ無効にする」「デフォルトでcacheを無効にして、一部だけ有効にする」どちらも可能になることが嬉しいですね...!
関数単位でcacheさせる
"use cache"
は関数単位でも定義可能です。
async function getNotice() {
"use cache"
const response = await fetch(...)
const data = await response.json()
return data.notice;
}
cacheTag()
でcacheをタグ付けする
cacheTag()
は、cacheしたデータをpurge(削除)したいときに使用します。
基本的にcacheはkeyとデータを紐づけて管理しますが、Next.jsではkeyを定義しなくてもNext.js内でデータを管理しておくことができます。しかし、そうすると意図的にcacheを消したい時に、開発者はkeyがわからないため、purgeすることができません。そのため、この機能を使用することで開発者が意図的にcacheしたデータをpurgeすることができるようになります。よりリソース単位でcacheを管理しやすくなりますね!
import { cacheTag } from 'next/cache';
async function getNotice() {
'use cache';
cacheTag('my-tag');
}
cacheLife()
でcacheの有効期間を宣言する
cacheLife()
は、cacheの有効期間を指定したいときに使用します。例えば1時間ごとに新しいデータを取得したいときなどに使うことができます。これは以前のfetch()
のrevalidate
とほとんど同じ役割なのかなと思います。
"use cache"
import { unstable_cacheLife as cacheLife } from 'next/cache'
export default async function Page() {
cacheLife("minutes")
return ...
}
最後に
いかがでしたでしょうか。"use cache"
の登場により、複雑だったNext.jsのcacheが少しシンプルになり、cache戦略が大きく変わってくるような機能だなと感じました。個人的にはコンポーネント・関数単位でcacheを制御できることが嬉しいなあと感じました。まだまだ進化するNext.jsの今後もとても楽しみです!
Discussion