コンテンツにスキップ

Chapter 10: Partial Prerendering

実際のプロジェクトで変更する必要はありません

Partial Prerendering は Next.js 14 の実験的機能で,next@canary を利用したときのみ有効です。この章では概念と操作手順を学びますが,ローカル環境のコードを実際に書き換える必要はありません。

前章までに静的・動的レンダリングとストリーミングを確認しました。この章では Partial Prerendering(PPR) を使い,同じルート内で静的コンテンツと動的コンテンツを組み合わせる考え方を押さえます。

注意(実験的機能) Partial Prerendering は Next.js 14 で導入された実験的機能です。安定化に伴い本章の内容は更新される可能性があります。PPR は 安定版ではなく canary 版(next@canary でのみ利用できます。本番環境での使用はまだ推奨されません。

canary 版をインストールするには次を実行します。

Terminal
pnpm install next@canary

この章で学ぶこと

  • Partial Prerendering とは何か
  • Partial Prerendering の仕組み

静的ルートと動的ルート

多くのWebアプリでは,アプリ全体あるいは特定のルートに対して,静的動的のどちらかを選びます。Next.js では,あるルートで動的な処理(例:DB クエリ)を呼び出すと,そのルート全体が動的になります。

しかし実際には,ほとんどのルートは完全な静的でも完全な動的でもありません。 例として EC サイトを考えると,製品ページの大部分(商品情報など)は静的にして高速表示し,ユーザーのカートやおすすめ商品のような個別で頻繁に変わる部分は動的にしたいはずです。

ダッシュボードページではどうでしょうか。どのコンポーネントを静的にし,どれを動的にしますか?

alt text

  • <SideNav>:データに依存せずユーザー固有でもない → 静的にできる。
  • <Page> 内のコンポーネント:頻繁に変わるユーザー固有のデータに依存 → 動的にする。

Partial Prerendering とは?

Next.js 14 で実験的に導入された新しいレンダリングモデルで,同一ルート内で静的と動的を組み合わせることができます。例として,製品ページを部分的にプリレンダリングする場合:

alt text

  • まず 静的なルートシェル(ナビゲーションや製品情報など)を配信し,初期表示を高速化
  • シェル内の「穴(hole)」にあたる領域に,カートやおすすめ商品のような動的コンテンツ非同期で読み込まれる。
  • これらの非同期部分は並列ストリーミングされ,全体のロード時間を短縮。

「穴(holes)」=リクエスト時に動的コンテンツが非同期で読み込まれる場所


Partial Prerendering の仕組み

PPR は前章で扱った React Suspense を利用し,特定部分のレンダリングを条件(例:データの取得)まで遅延します。

  • ビルド時(または再検証時)に,静的コンテンツ+Suspense のフォールバックを含む 静的シェル を生成。
  • 動的コンテンツのレンダリングはユーザーがルートをリクエストした時点まで延期されます。
  • コンポーネントを Suspense で包むこと自体はそのコンポーネントを動的化する宣言ではなく,静的コードと動的コードの境界として機能します。

Partial Prerendering を実装する

まず,next.config.ts に PPR オプションを追加して有効化します。

next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    ppr: 'incremental'
  }
};

export default nextConfig;

'incremental' は,特定のルートから段階的に PPR を採用できる設定です。

次に,ダッシュボードのレイアウトに segment config を追加します。

/app/dashboard/layout.tsx
import SideNav from '@/app/ui/dashboard/sidenav';

export const experimental_ppr = true;

// ...

これで設定は完了です。開発環境では違いが分かりにくいかもしれませんが,本番環境ではパフォーマンス向上が見込めます。Next.js が静的な部分をプリレンダリングし,動的な部分はリクエスト時に後追いでレンダリングします。

PPR の良い点は,コードを大きく書き換える必要がないことです。ルート内の動的部分を Suspense で包んでいれば,Next.js が自動的に静的・動的の境界を認識します。

PPR は将来的に,静的サイトと動的レンダリングの利点を統合したデフォルトのレンダリングモデルになり得ると考えています。ただし現時点では実験的であり,安定化後にデフォルト化を目指しています。

※ この章の変更はここで元に戻して,次の章へ進んでも構いません。


まとめ

これまでに,アプリのデータ取得を最適化するために以下を行ってきました。

  • アプリケーションコードと同一リージョンにデータベースを作成し,サーバーとDB間のレイテンシを低減。
  • React Server Components でサーバー側取得:重い取得やロジックをサーバーにとどめ,クライアントJSを削減し,DBシークレットの露出を防止。
  • SQL で必要なデータだけ取得し,リクエスト転送量とクライアントでの変換処理を削減。
  • 必要に応じて JavaScript で並列取得Promise.all など)を実施。
  • ストリーミングで遅いリクエストがページ全体をブロックしないようにし,ユーザーが待たずに操作を開始できるようにした。
  • データ取得を必要なコンポーネントの中へ移動し,どの部分が動的であるべきかを明確化。

次章では,データ取得でよく必要となる 検索(Search)ページネーション(Pagination) の2つのパターンを扱います。