コンテンツにスキップ

10

部分プリレンダリング

これまでは、静的レンダリングと動的レンダリング、そしてデータに依存する動的コンテンツのストリーミング方法について学んできました。この章では、同じルートで静的レンダリング、動的レンダリング、ストリーミングを組み合わせる方法、すなわち部分プリレンダリング (PPR) について学びます。

部分プリレンダリングは、Next.js 14 で導入された実験的な機能です。この機能が安定するにつれて、このページのコンテンツは更新される可能性があります。PPR は Next.js のカナリアリリース (next@canary) でのみ利用可能であり、Next.js の安定版では利用できません。現時点では、本番環境で部分プリレンダリングを使用することは推奨していません。

Next.js のカナリアリリースをインストールするには、以下を実行してください。

pnpm install next@canary

このチャプターでは...

取り上げるトピックは以下の通りです。

部分プリレンダリングとは

部分プリレンダリングの仕組み

静的 vs. 動的ルート

今日構築されるほとんどの Web アプリケーションでは、アプリケーション全体に対して静的レンダリングと動的レンダリングのどちらかを選択するか、特定のルートに対して選択します。そして Next.js では、ルートで動的関数(データベースのクエリなど)を呼び出すと、ルート全体が動的になります。

しかし、ほとんどのルートは完全に静的または動的ではありません。たとえば、eコマースサイトを考えてみましょう。商品情報ページの大部分を静的にレンダリングしたいかもしれませんが、ユーザーのカートやおすすめ商品については動的に取得したい場合があります。これにより、ユーザーにパーソナライズされたコンテンツを表示できます。

ダッシュボードページに戻って、どのコンポーネントを静的、どのコンポーネントを動的と考えるでしょうか?

準備ができたら、以下のボタンをクリックして、ダッシュボードルートをどのように分割するかを見てみましょう。

部分プリレンダリングとは

Next.js 14 では、**部分プリレンダリング**の実験的なバージョンが導入されました。これは、同じルートで静的レンダリングと動的レンダリングの利点を組み合わせることができる新しいレンダリングモデルです。例えば

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

ユーザーがルートにアクセスすると

  • ナビバーと商品情報を含む静的なルートシェルが提供され、高速な初期ロードが保証されます。
  • シェルは、カートやおすすめ商品などの動的コンテンツが非同期でロードされる場所の「穴」を残します。
  • 非同期の穴は並列でストリーミングされ、ページの全体的なロード時間が短縮されます。

部分プリレンダリングの仕組み

部分プリレンダリングでは、React の Suspense (前の章で学習した) を使用して、条件が満たされるまで(例:データがロードされるまで)アプリケーションの一部レンダリングを遅延させます。

Suspense のフォールバックは、静的コンテンツとともに初期 HTML ファイルに埋め込まれます。ビルド時(または再検証時)に、静的コンテンツがプリレンダリングされて静的シェルが作成されます。動的コンテンツのレンダリングは、ユーザーがルートをリクエストするまで延期されます。

コンポーネントを Suspense でラップしても、コンポーネント自体が動的になるわけではありません。むしろ、Suspense は静的コードと動的コードの境界として使用されます。

ダッシュボードルートに PPR を実装する方法を見てみましょう。

部分プリレンダリングの実装

next.config.ts ファイルに ppr オプションを追加して、Next.js アプリで PPR を有効にします。

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

'incremental' 値は、特定のルートに対して PPR を採用することを可能にします。

次に、ダッシュボードレイアウトに experimental_ppr セグメント設定オプションを追加します。

/app/dashboard/layout.tsx
import SideNav from '@/app/ui/dashboard/sidenav';
 
export const experimental_ppr = true;
 
// ...

これで完了です。開発環境ではアプリケーションに違いが見られないかもしれませんが、本番環境ではパフォーマンスの向上に気づくはずです。Next.js はルートの静的パーツをプリレンダリングし、動的パーツはユーザーがリクエストするまで遅延させます。

部分プリレンダリングの優れた点は、コードを変更する必要がないことです。動的な部分を Suspense でラップしている限り、Next.js はルートのどの部分が静的で、どの部分が動的であるかを認識します。

私たちは、PPR がWeb アプリケーションのデフォルトレンダリングモデルになる可能性を秘めていると信じており、静的サイトと動的レンダリングの最良の部分を組み合わせています。しかし、それはまだ実験的なものです。将来的には安定化し、Next.js での構築のデフォルトの方法にしたいと考えています。

これでこれらの変更を元に戻し、次の章に進むことができます。

まとめ

これまでのアプリケーションでのデータ取得の最適化について、いくつか確認しましょう。

  1. アプリケーションコードと同じリージョンにデータベースを作成し、サーバーとデータベース間のレイテンシーを削減しました。
  2. React Server Components でサーバーサイドでデータを取得しました。これにより、コストのかかるデータ取得やロジックをサーバーに保持し、クライアントサイドの JavaScript バンドルを削減し、データベースのシークレットがクライアントに公開されるのを防ぐことができます。
  3. SQL を使用して必要なデータのみを取得し、各リクエストで転送されるデータ量と、インメモリでデータを変換するために必要な JavaScript の量を削減しました。
  4. 可能な限り、JavaScript でデータ取得を並列化しました。
  5. ストリーミングを実装して、遅いデータリクエストがページ全体をブロックするのを防ぎ、ユーザーがすべてがロードされるのを待たずに UI と対話し始められるようにしました。
  6. データ取得を必要とするコンポーネントまで下に移動させ、ルートのどの部分が動的であるべきかを分離しました。

次の章では、データ取得時に実装する必要がある可能性のある 2 つの一般的なパターン、検索とページネーションについて説明します。

チャプターを完了しました。10

Next.js 14 で導入された新しいレンダリングモデルである部分プリレンダリングについて学びました。

次へ

11: 検索とページネーションの追加

Next.js API を使用して検索とページネーションを実装する方法を学びます。