部分的なプリレンダリング
部分的なプリレンダリング (PPR) を使用すると、静的コンポーネントと動的コンポーネントを同じルートで組み合わせることができます。
ビルド中、Next.js はルートを可能な限りプリレンダリングします。受信リクエストからの読み取りなど、動的コードが検出された場合は、関連するコンポーネントを React Suspense境界でラップできます。その後、Suspense の境界のフォールバックがプリレンダリングされた HTML に含まれます。
注: 部分的なプリレンダリングは実験的な機能であり、変更される可能性があります。本番環境での使用にはまだ対応していません。


🎥 視聴: PPR の理由とその仕組み → YouTube (10 分)。
背景
PPR を使用すると、Next.js サーバーはプリレンダリングされたコンテンツを即座に送信できます。
クライアントからサーバーへのウォーターフォールを防ぐために、動的コンポーネントは、最初のプリレンダーを提供しながら、サーバーから並行してストリーミングを開始します。これにより、動的コンポーネントは、ブラウザーでクライアント JavaScript がロードされる前にレンダリングを開始できます。
各動的コンポーネントに対して多数の HTTP リクエストを作成することを防ぐために、PPR は静的なプリレンダーと動的なコンポーネントを 1 つの HTTP リクエストに結合できます。これにより、各動的コンポーネントに複数のネットワークラウンドトリップは必要ありません。
部分的なプリレンダリングの使用
段階的な導入 (バージョン 15)
Next.js 15 では、next.config.js
の ppr
オプションを incremental
に設定し、ファイルの先頭に experimental_ppr
ルート構成オプションをエクスポートすることで、レイアウトと ページで部分的なプリレンダリングを段階的に採用できます。
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
ppr: 'incremental',
},
}
export default nextConfig
import { Suspense } from "react"
import { StaticComponent, DynamicComponent, Fallback } from "@/app/ui"
export const experimental_ppr = true
export default function Page() {
return {
<>
<StaticComponent />
<Suspense fallback={<Fallback />}>
<DynamicComponent />
</Suspense>
</>
};
}
知っておくと良いこと:
experimental_ppr
を持たないルートはデフォルトでfalse
になり、PPR を使用してプリレンダリングされません。各ルートで PPR を明示的にオプトインする必要があります。experimental_ppr
は、ネストされたレイアウトやページを含む、ルートセグメントのすべての子に適用されます。すべてのファイルに追加する必要はなく、ルートの最上位セグメントのみに追加します。- 子セグメントの PPR を無効にするには、子セグメントで
experimental_ppr
をfalse
に設定できます。
PPR の有効化 (バージョン 14)
バージョン 14 の場合は、ppr
オプションを next.config.js
ファイルに追加することで有効にできます。これは、アプリケーション内のすべてのルートに適用されます。
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
ppr: true,
},
}
export default nextConfig
動的コンポーネント
next build
中にルートのプリレンダーを作成するとき、Next.js は動的 API が React Suspense でラップされていることを要求します。その後、fallback
がプリレンダーに含まれます。
たとえば、cookies
や headers
のような関数を使用する場合。
import { cookies } from 'next/headers'
export async function User() {
const session = (await cookies()).get('session')?.value
return '...'
}
このコンポーネントは、Cookie を読み取るために受信リクエストの確認が必要です。PPR でこれを使用するには、コンポーネントを Suspense でラップする必要があります。
import { Suspense } from 'react'
import { User, AvatarSkeleton } from './user'
export const experimental_ppr = true
export default function Page() {
return (
<section>
<h1>This will be prerendered</h1>
<Suspense fallback={<AvatarSkeleton />}>
<User />
</Suspense>
</section>
)
}
コンポーネントは、値がアクセスされたときにのみ動的レンダリングを選択します。
たとえば、page
から searchParams
を読み取っている場合、この値を prop として別のコンポーネントに転送できます。
import { Table } from './table'
export default function Page({
searchParams,
}: {
searchParams: { sort: string }
}) {
return (
<section>
<h1>This will be prerendered</h1>
<Table searchParams={searchParams} />
</section>
)
}
テーブルコンポーネント内で、searchParams
から値にアクセスすると、コンポーネントは動的に実行されます。
export async function Table({
searchParams,
}: {
searchParams: Promise<{ sort: string }>
}) {
const sort = (await searchParams).sort === 'true'
return '...'
}
お役に立ちましたか?