前回
Next.jsのチュートリアルをやってみる【ストリーミング編】はじめに
前回までは静的レンダリング・動的レンダリング・ストリーミングについて学んできました。今回はPartial Prerendering(PPR)を使用し、一つのルート内で組み合わせる方法を学んでいきます。
静的ルート vs 動的ルート
Webアプリケーションの大多数はアプリケーション全体または特定のルートに対して、静的レンダリングと動的レンダリングのどちらかを選択します。また、Next.jsではルート内で動的な関数を呼び出すと、ルート全体が動的になります。
しかし、ほとんどのルートは完全に静的でも動的でもありません。例えば、eコマースサイトを考えてみましょう。所品ページの大部分を静的にレンダリングしたいかもしれませんが、ユーザーのカートやおすすめ商品を動的に取得したいかもしれません。このようにすることでユーザーにパーソナライズされたコンテンツを表示することができます。
ダッシュボートの場合はどうでしょうか。<SideNav>
コンポーネントはデータに依存せず、ユーザーに合わせてカスタマイズされないので静的にすることができます。その他の<Page>
のコンポーネントはデータに依存し、ユーザーに合わせてカスタマイズされるので動的である必要があります。
Partial Prerenderingとは?
同じルートで静的レンダリングと動的レンダリングの利点を組み合わせることができる新しいレンダリングモデルです。このPartial Prerendering(PPR)はNext.js 14で実験的に導入されているため、安定性が改善されるにつれて更新される可能性があります。
Partial Prerenderingの仕組み
Partial Prerenderingは、前回学んだSuspenseを使用して、何らかの条件が満たされるまで一部のレンダリングを延期します。
Suspenseのフォールバックは、静的コンテンツとともに最初のHTMLファイルに埋め込まれます。ビルド時に静的コンテンツはプリレンダリングされ、静的シェルが作成されます。動的コンテンツのレンダリングはユーザーがルートをリクエストするまで延期されます。
コンポーネントをSuspenseでラップしても、コンポーネント自体がダイナミックになるわけではありません。むしろ、Suspenseは静的コードと動的コードの境界として使われます。
Partial Prerenderingの実装
PPRについて学んだところで、早速ダッシュボートに実装してみましょう。
next.config.mjs
ファイルにppr
オプションを追加してNext.jsアプリのPPRを有効にしましょう。
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
ppr: 'incremental',
},
};
export default nextConfig;
incremental
は特定のルートにPPRを採用することができます。
続いてダッシュボードにPPRを適用するために、ダッシュボードのレイアウトにexperimental_ppr
セグメント設定オプションを追加します。
import SideNav from '@/app/ui/dashboard/sidenav';
export const experimental_ppr = true;
// ...
これで、PPRをダッシュボードに追加することができました。開発環境ではアプリケーションの違いが分からないかもしれません。ですが本番環境ではパフォーマンスの向上が感じられると思います。
PPRはコードを変更しなくても使用することができるので、導入がとても簡単です。ルートの動的部分をラップするために<Suspense>
を使用している限り、Next.jsはルートのどの部分が静的で、どの部分が動的かを判断することができます。
PPRは静的レンダリングと動的レンダリングの長所を併せ持ち、ウェブアプリケーションのデフォルトのレンダリングモデルになる可能性を秘めているとNext.jsは考えているため、将来的にはデフォルトのビルド方法にする方向性のようです。
ここまでで行った最適化
- アプリケーションコードと同じリージョンにデータベースを作成し、サーバーとデータベース間のレイテンシーを削減。
- React Server Components (RSC) を使用してサーバー上でデータを取得するように変更し、データフェッチとロジックをサーバー上に維持し、クライアント側のJavaScriptを減らすことで公開したくないデータベースの秘密をクライアントに公開されることを防いだ。
- SQLを使用して必要なデータだけをフェッチし、リクエスト毎に転送されるデータ量とデータを変換するためのJavaScriptの量を減らした。
- データ・フェッチを並列化した。
- ストリーミングを実装して遅いデータリクエストがページ全体をブロックするのを防ぎ、ユーザーがすべての読み込みを待つ必要なくUIとのやり取りを開始できるようにした。
- データフェッチを必要なコンポーネントに移動させ、ルートのどの部分が動的であるべきかを分離した。
まとめ
- Partial Prerendering (PPR) は同じルートで部分的にプリレンダリングする機能
- コードを変更せずに導入することができるため、簡単に利用できる。
<Suspense>
を使用することで、Next.jsがどの部分が静的かまたは動的かを判断することができる