Partial Prerendering(1)
それでは、次にNext.js 14で追加された新機能であるPartial Prerendering(パーシャルプリレンダリング、PPR)について見ていきましょう。Partial Prerenderingは、App Routerのページを部分的に動的にしている場合でも、ページ全体としては事前にレンダリングしておいたものを静的配信する機能です。これにより、動的な部分だけをクライアントサイドで生成することで、ページの表示速度を向上させることができます。
Static RenderingとDynamic Rendering
Partial Prerenderingを理解するためには、まずServer ComponentsにおけるStatic Rendering(静的レンダリング)とDynamic Rendering(動的レンダリング)の違いを理解する必要があります。ここでいう「レンダリング」とは、一般的にイメージされる画面への描画のことではなく、Reactコンポーネントを定義している関数を実行して、その結果をUIのツリー構造(いわゆるVirtual DOM)に変換することを指します。HTMLファイルの生成を伴う場合もありますが、伴わない場合もあります。
特に今回は、Server Componentsを実行してツリーを作成する処理についての話題を扱います(図1)。
Static Renderingは、ページ全体をビルド時(デプロイ前)にレンダリングしておき、その結果を静的ファイルとして配信する方法です。この方法でレンダリング済みのファイルは、CDNにキャッシュできることが多く、高速な表示を実現できます。特段の理由がなければ、すべてのServer ComponentsはStatic Renderingでレンダリングされます。
一方、Dynamic RenderingはServer Componentsを動的に処理する方法です。サーバーにリクエストがあったときに、その時点でServer Componentsの関数を実行してレンダリングを行います。この方法は、Dynamic APIと呼ばれる所定のAPIを利用している場合や、明示的に動的な処理を指示した場合に利用されます。画面から表示の要求があるたびに実行されるため、CDN等にキャッシュすることはできません。
Static Renderingを含むページの挙動
Partial Prerenderingとの挙動の差異を理解するために、まずはStatic Renderingが行われるページの挙動を確認してみましょう。リスト4は、Static Renderingが行われるページの例です。
// app/page.js export default async function Home() { return ( <div className="flex flex-col h-screen"> <Header /> <div className="flex flex-1"> <SideMenu /> {/* メインコンテンツ */} <main className="flex-1 p-6"> <h2 className="text-xl font-bold mb-4">メイン</h2> <p>ここは静的なページです</p> </main> </div> </div> ); } function Header() { // 省略 } function SideMenu() { // 省略 }
実際に動かしてみると、図2のような画面が表示されます。
特に何かの通信結果を使うわけでもなく、静的なコンテンツを表示するだけのページです。これはビルド時に静的ファイルが作られるはずなので、ビルドしてみましょう(リスト5)。
$ npm run build # 省略 Route (app) Size First Load JS ┌ ○ / 139 B 100 kB ├ ○ /_not-found 896 B 101 kB └ ○ /server-actions 139 B 100 kB + First Load JS shared by all 99.9 kB ├ chunks/4bd1b696-80bcaf75e1b4285e.js 52.5 kB ├ chunks/517-d083b552e04dead1.js 45.5 kB └ other shared chunks (total) 1.88 kB ○ (Static) prerendered as static content
ビルド結果を見ると、app/page.js
に対応するルートディレクトリ(/
)に、Static Renderingが行われたことを示すマルがついています。 .next/server/app/index.html
にあるHTMLファイルを見てみると、図3のように、静的なコンテンツが含まれていることが確認できます。
これだけだと、従来のStatic Site Generation(SSG)と変わらないように見えますが、App Routerらしい点として、 .next/server/app/index.rsc
にServer Componentsの処理結果であるツリー情報が生成されています(図4)。
サイトに初めて来たときにはHTMLが使われますが、その後のページ遷移では、このツリー情報を使ってクライアントサイドでブラウザへのレンダリングが行われます。サーバーサイドでもServer Componentsの再評価を行わないため、高速な表示が実現できます。