コンテンツにスキップ
アプリケーションの構築レンダリング部分的なプリレンダリング

部分的なプリレンダリング

部分的なプリレンダリング (PPR) を使用すると、静的コンポーネントと動的コンポーネントを同じルートで組み合わせることができます。

ビルド中、Next.js はルートを可能な限りプリレンダリングします。受信リクエストからの読み取りなど、動的コードが検出された場合は、関連するコンポーネントを React Suspense境界でラップできます。その後、Suspense の境界のフォールバックがプリレンダリングされた HTML に含まれます。

注: 部分的なプリレンダリングは実験的な機能であり、変更される可能性があります。本番環境での使用にはまだ対応していません。

Partially Prerendered Product Page showing static nav and product information, and dynamic cart and recommended products

🎥 視聴: PPR の理由とその仕組み → YouTube (10 分)

背景

PPR を使用すると、Next.js サーバーはプリレンダリングされたコンテンツを即座に送信できます。

クライアントからサーバーへのウォーターフォールを防ぐために、動的コンポーネントは、最初のプリレンダーを提供しながら、サーバーから並行してストリーミングを開始します。これにより、動的コンポーネントは、ブラウザーでクライアント JavaScript がロードされる前にレンダリングを開始できます。

各動的コンポーネントに対して多数の HTTP リクエストを作成することを防ぐために、PPR は静的なプリレンダーと動的なコンポーネントを 1 つの HTTP リクエストに結合できます。これにより、各動的コンポーネントに複数のネットワークラウンドトリップは必要ありません。

部分的なプリレンダリングの使用

段階的な導入 (バージョン 15)

Next.js 15 では、next.config.jsppr オプションを incremental に設定し、ファイルの先頭に experimental_ppr ルート構成オプションをエクスポートすることで、レイアウトページで部分的なプリレンダリングを段階的に採用できます。

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  experimental: {
    ppr: 'incremental',
  },
}
 
export default nextConfig
app/page.tsx
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_pprfalse に設定できます。

PPR の有効化 (バージョン 14)

バージョン 14 の場合は、ppr オプションを next.config.js ファイルに追加することで有効にできます。これは、アプリケーション内のすべてのルートに適用されます。

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  experimental: {
    ppr: true,
  },
}
 
export default nextConfig

動的コンポーネント

next build 中にルートのプリレンダーを作成するとき、Next.js は動的 API が React Suspense でラップされていることを要求します。その後、fallback がプリレンダーに含まれます。

たとえば、cookiesheaders のような関数を使用する場合。

app/user.tsx
import { cookies } from 'next/headers'
 
export async function User() {
  const session = (await cookies()).get('session')?.value
  return '...'
}

このコンポーネントは、Cookie を読み取るために受信リクエストの確認が必要です。PPR でこれを使用するには、コンポーネントを Suspense でラップする必要があります。

app/page.tsx
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 として別のコンポーネントに転送できます。

app/page.tsx
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 から値にアクセスすると、コンポーネントは動的に実行されます。

app/table.tsx
export async function Table({
  searchParams,
}: {
  searchParams: Promise<{ sort: string }>
}) {
  const sort = (await searchParams).sort === 'true'
  return '...'
}