Next.js(App Router)のFull Route Cache
Next.js(App Router)には静的なページをキャッシュするための機構としてFull Route Cacheが用意されています。
Full Route Cacheの挙動
src/app/page.tsx
を以下のようにしてNextアプリを起動してみます
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を無効にすることができます。
+ export const dynamic = 'force-dynamic'
// or
+ export const revalidate = 0
export default async function Home() {
const time = Date.now()
return (
<h1>{time}</h1>
);
}
キャッシュを破棄
Full Route Cacheを有効にしたままキャッシュを破棄するにはページのキャッシュを破棄するrevalidate
を行います。
src/app/api/route.ts
というファイルにrevalidate
用の処理を記述してNextアプリを起動してみます。
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利用時の挙動を見ていきましょう。
以下のように外部データを取得して表示するページを作成します。
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キャッシュの永続化がされないように指定します。
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