静的速度と動的鮮度のジレンマ
従来のNext.js開発者は、静的生成(高速だが古くなりやすい)かサーバーサイドレンダリング(新鮮だが遅い)の二者択一を迫られていました。Partial Prerendering(PPR)は、1ページの中で両方のアプローチを組み合わせることで、このトレードオフを解消します。静的HTMLシェルを即座に配信し、動的コンテンツをReact Suspense経由でストリーミング読み込みします。
PPRの仕組み
PPRはReact Suspenseを使用して静的な境界と動的な境界を識別します。ビルド時に静的シェルがプリレンダリングされ、リクエスト時にSuspenseのフォールバックが動的コンテンツのストリーミングに置き換えられます:
// page.tsx
import { Suspense } from "react";
export default function HomePage() {
return (
<div>
{/* 静的 — ビルド時にプリレンダリング */}
<Header />
{/* 動的 — リクエスト時にストリーミング */}
<Suspense fallback={<Skeleton />}>
<PersonalizedGreeting />
</Suspense>
</div>
);
}
設定方法
next.config.tsでPPRを有効化します:
// next.config.ts
const nextConfig = {
experimental: {
ppr: true,
},
};
export default nextConfig;
ルート単位で制御する場合は、experimental_pprをエクスポートします。
静的シェルとストリーミング境界
PPRページがリクエストされると、ブラウザは以下の順序でコンテンツを受信します:
- 静的シェル — SuspenseでラップされていないコンポーネントのHTMLとCSS
- Suspenseフォールバック — 動的コンテンツ読み込み中のプレースホルダー
- ストリーミング動的コンテンツ — 各Suspense境界が解決されるたびにUIが更新
パフォーマンス比較
| 指標 | SSR | SSG | PPR |
|---|---|---|---|
| TTFB | 遅い | 高速 | 高速 |
| FCP | 中程度 | 高速 | 高速 |
| 動的データ鮮度 | 新鮮 | 古い可能性 | 新鮮 |
| サーバー負荷 | 高 | 最小 | 低 |
ユースケース
PPRは静的コンテンツとパーソナライズ要素が混在するページに最適です:
- ECサイト商品ページ:商品画像・説明は静的、在庫状況や価格は動的
- ダッシュボード:ナビゲーションやレイアウトは静的、メトリクスや通知は動的
- コンテンツサイト:記事本文は静的、コメントやレコメンデーションは動的
SEOへの影響
PPRページは完全にインデックス可能です。SEOに重要なコンテンツはすべて静的シェルに含まれ、検索エンジンのクローラーは完全な静的コンテンツを受け取ります。メタタグ、OGP画像、構造化データもすべてプリレンダリングされます。
他のレンダリング戦略との比較
| 戦略 | ビルド時 | リクエスト時 | エッジキャッシュ |
|---|---|---|---|
| SSG | 全ページ | なし | 全ページ |
| SSR | なし | 全ページ | リクエスト単位 |
| ISR | 大半のページ | 再検証 | 全ページ |
| PPR | 静的シェル | 動的境界 | シェル+ストリーミング |
まとめ
Partial Prerenderingはレンダリング戦略の考え方に根本的な変革をもたらします。静的な速度と動的な鮮度を二者択一する必要はもうありません。動的コンテンツをSuspense境界でラップするだけで、インスタントな静的シェルとリアルタイムのインタラクティビティを同時に実現できます。PPRは今後、Next.jsアプリケーションのデフォルトレンダリング戦略になる可能性が高いと言えるでしょう。
