🎲

Next.js(App Router)のFull Route Cache

2024/05/15に公開

Next.js(App Router)には静的なページをキャッシュするための機構としてFull Route Cacheが用意されています。

https://nextjs.org/docs/app/building-your-application/caching#full-route-cache

Full Route Cacheの挙動

src/app/page.tsxを以下のようにしてNextアプリを起動してみます

src/app/page.tsx
export default async function Home() {
  const time = Date.now()
  return (
    <h1>{time}</h1>
  );
}

念の為、キャッシュデータを削除してから起動を行います。

rm -rf .next/ && npm run build && npm start

ブラウザで表示を確認するとリロードを行っても<h1>{time}</h1>の内容は更新されません。

このようにデータ取得が無いページではキャッシュした情報が配信されるようにようになります。

キャッシュを無効

このままでは時間が正しく表示されないのでFull Route CacheをOFFにしてみましょう。

ページの設定が可能なRoute Segment Configのdynamicオプションにforce-dynamicを指定、もしくはrevalidateオプションに0を指定することでFull Route Cacheを無効にすることができます。

src/app/page.tsx
+ export const dynamic = 'force-dynamic'
// or 
+ export const revalidate = 0

export default async function Home() {
  const time = Date.now()
  return (
    <h1>{time}</h1>
  );
}

https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic

キャッシュを破棄

Full Route Cacheを有効にしたままキャッシュを破棄するにはページのキャッシュを破棄するrevalidateを行います。

src/app/api/route.tsというファイルにrevalidate用の処理を記述してNextアプリを起動してみます。

src/app/api/route.tsx
import { NextResponse } from 'next/server';
import { revalidatePath } from 'next/cache';

export function GET() {
    revalidatePath('/')
    return NextResponse.json({ message: 'revalidate page' });
}

http://localhost:3000/を表示して何度リロードしても時間は更新されませんが、一度http://localhost:3000/api/にアクセスしてrevalidateを行った後にhttp://localhost:3000/のリロードを行うと時間が更新されます。

fetch利用時の挙動①

fetch利用時の挙動を見ていきましょう。

以下のように外部データを取得して表示するページを作成します。

src/app/page.tsx
export default async function Home() {
  const time = Date.now()
  const response = await fetch('https://dummyjson.com/products/1')
        .then(res => res.json())
  return (
    <>
      <h1>{time}</h1>
      <h2>{response.title}</h2>
    </>
  );
}

これでNextアプリを起動してリロードしてもh1の日時は更新されません。

fetch利用時の挙動② (cache:"no-store")

以下のようにfetch時にcache:"no-store"を指定してDataキャッシュの永続化がされないように指定します。

src/app/page.tsx
export default async function Home() {
  const time = Date.now()
  const response = await fetch('https://dummyjson.com/products/1',{
    cache:"no-store"
  }).then(res => res.json())
  return (
    <>
      <h1>{time}</h1>
      <h2>{response.title}</h2>
    </>
  );
}

そうすると、これでNextアプリを起動してリロードすればh1の日時が更新されるようになります。

結論

あまり意識する必要はありませんが、Full Route Cacheはfetchによるデータ更新が発生しないページ(RSC)をキャッシュしておきページの描画を最適化してくれるようになります。

株式会社トゥーアール

Discussion