Gemcook Tech Blog
🏛️

Next.jsの"use cache"の概要を掴みたいあなたへ

2024/10/29に公開

はじめに

先日、Next.js Conf 2024が開催されました!(日本時間だと眠い時間帯でしたね...)

https://nextjs.org/conf

そこで話題になったのが"use cache"ではないでしょうか?今回は以下のブログをもとに、"use cache"の概要について解説していきたいと思います。"use cache"がどんなものかを掴みたい人はぜひ最後までお読みください!

https://nextjs.org/blog/our-journey-with-caching

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"を定義することで対応できます。

app/page.tsx
"use cache"
 
export default async function Page() {
  return fetch(...) // no error
}

部分的にcacheさせる

基本的にはデフォルトでcacheさせたいが、一部の処理を動的にしたい場合などは以下のようにします。app/layout.tsx"use cache"を定義することで、基本的にはcacheを有効にさせつつ、app/page.tsxで一部だけ動的にデータをfetchすることも可能です。

app/layout.tsx
"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>
}
app/page.tsx
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の今後もとても楽しみです!

Gemcook Tech Blog
Gemcook Tech Blog

Discussion