use cache
use cache
ディレクティブは、コンポーネントまたは関数、あるいはその両方をキャッシュするように指定します。ファイルの先頭で使用して、ファイル内のすべてのエクスポートがキャッシュ可能であることを示すことも、関数やコンポーネントの先頭にインラインで使用して、Next.jsに返り値がキャッシュされ、後続のリクエストで再利用されるべきであることを通知することもできます。これは実験的なNext.jsの機能であり、use client
や use server
のようなネイティブなReactの機能ではありません。
使用方法
next.config.ts
ファイルで useCache
フラグを有効にすることで、use cache
ディレクティブのサポートを有効にできます。
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
useCache: true,
},
}
export default nextConfig
さらに、dynamicIO
フラグが設定されている場合も、use cache
ディレクティブが有効になります。
次に、ファイル、コンポーネント、または関数レベルで use cache
ディレクティブを使用できます。
// File level
'use cache'
export default async function Page() {
// ...
}
// Component level
export async function MyComponent() {
'use cache'
return <></>
}
// Function level
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
覚えておくと良い点
use cache
は実験的なNext.jsの機能であり、use client
やuse server
のようなネイティブなReactの機能ではありません。- キャッシュされた関数に渡されるシリアライズ可能な引数 (またはプロップ) 、および親スコープから読み取るシリアライズ可能な値は、JSONのような形式に変換され、自動的にキャッシュキーの一部になります。
- シリアライズ不可能な引数、プロップ、またはクロージャの値は、キャッシュされた関数内で不透明な参照となり、単に渡されるだけで、検査や変更はできません。これらのシリアライズ不可能な値は、リクエスト時に埋め込まれるため、キャッシュキーの一部にはなりません。
- 例えば、キャッシュされた関数はJSXを
children
プロップとして受け取り、<div>{children}</div>
を返すことができますが、実際のchildren
オブジェクトを内省することはできません。
- 例えば、キャッシュされた関数はJSXを
- キャッシュ可能な関数の返り値もシリアライズ可能である必要があります。これにより、キャッシュされたデータを正しく保存および取得できます。
use cache
ディレクティブを使用する関数は、状態の変更、DOMの直接操作、一定間隔でのコード実行のためのタイマー設定など、いかなる副作用も持たないようにしてください。- 部分的なプリレンダリング と組み合わせて使用すると、
use cache
を持つセグメントは静的HTMLシェルの一部としてプリレンダリングされます。 - JSONデータのみをサポートする
unstable_cache
とは異なり、use cache
はコンポーネントのレンダリング出力を含む、Reactがレンダリングできるあらゆるシリアライズ可能なデータをキャッシュできます。
例
use cache
を使用したルート全体のキャッシュ
ルート全体をプリレンダリングするには、layout
ファイルと page
ファイルの**両方**の先頭に use cache
を追加します。これらの各セグメントはアプリケーション内の独立したエントリポイントとして扱われ、個別にキャッシュされます。
'use cache'
export default function Layout({ children }: { children: ReactNode }) {
return <div>{children}</div>
}
page
ファイルでインポートされ、ネストされたコンポーネントは、page
のキャッシュ動作を継承します。
'use cache'
async function Users() {
const users = await fetch('/api/users')
// loop through users
}
export default function Page() {
return (
<main>
<Users />
</main>
)
}
これは、以前に
export const dynamic = "force-static"
オプションを使用していたアプリケーションに推奨され、ルート全体がプリレンダリングされることを保証します。
use cache
を使用したコンポーネント出力のキャッシュ
コンポーネントレベルで use cache
を使用して、そのコンポーネント内で実行されるあらゆるフェッチや計算をキャッシュできます。アプリケーション全体でコンポーネントを再利用する場合、プロップが同じ構造を維持している限り、同じキャッシュエントリを共有できます。
プロップはシリアライズされてキャッシュキーの一部となり、シリアライズされたプロップが各インスタンスで同じ値を生成する限り、キャッシュエントリは再利用されます。
export async function Bookings({ type = 'haircut' }: BookingsProps) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
interface BookingsProps {
type: string
}
use cache
を使用した関数出力のキャッシュ
use cache
は任意の非同期関数に追加できるため、コンポーネントやルートのキャッシュのみに限定されません。ネットワークリクエストやデータベースクエリをキャッシュしたり、非常に時間のかかる計算をキャッシュしたりしたい場合があるでしょう。この種の処理を含む関数に use cache
を追加することで、その関数はキャッシュ可能になり、再利用時に同じキャッシュエントリを共有します。
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
再検証
デフォルトでは、use cache
ディレクティブを使用すると、Next.js は**15分の再検証期間**を設定します。Next.js はほぼ無限の有効期限を設定するため、頻繁な更新を必要としないコンテンツに適しています。
この再検証期間は、頻繁に変わることがないコンテンツに役立つかもしれませんが、cacheLife
および cacheTag
APIを使用してキャッシュ動作を設定できます。
これら両方のAPIは、クライアントとサーバーのキャッシュレイヤー全体に統合されているため、キャッシュのセマンティクスを1か所で設定し、それをどこにでも適用できます。
詳細については、cacheLife
および cacheTag
のドキュメントを参照してください。
無効化
キャッシュされたデータを無効化するには、revalidateTag
関数を使用できます。
詳細については、revalidateTag
のドキュメントを参照してください。
インターリービング
キャッシュ可能な関数にシリアライズ不可能な引数を渡す必要がある場合、それらを children
として渡すことができます。これは、children
の参照が変わってもキャッシュエントリに影響を与えないことを意味します。
export default async function Page() {
const uncachedData = await getData()
return (
<CacheComponent>
<DynamicComponent data={uncachedData} />
</CacheComponent>
)
}
async function CacheComponent({ children }: { children: ReactNode }) {
'use cache'
const cachedData = await fetch('/api/cached-data')
return (
<div>
<PrerenderedComponent data={cachedData} />
{children}
</div>
)
}
また、キャッシュ可能な関数内でServer Actionsを呼び出すことなく、キャッシュされたコンポーネントを介してClient Componentsに渡すこともできます。
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// Perform some server-side update
await db.update(...)
}
return <CacheComponent performUpdate={performUpdate} />
}
async function CachedComponent({
performUpdate,
}: {
performUpdate: () => Promise<void>
}) {
'use cache'
// Do not call performUpdate here
return <ClientComponent action={performUpdate} />
}
'use client'
export default function ClientComponent({
action,
}: {
action: () => Promise<void>
}) {
return <button onClick={action}>Update</button>
}
関連
お役に立ちましたか?