メインコンテンツまでスキップ

Server Components

React Server Componentsを使用すると、UIをサーバーでレンダリングし、オプションでキャッシュすることができます。Next.jsでは、レンダリング作業がさらにルートセグメントごとに分割され、ストリーミングや部分的なレンダリングを可能にし、3つの異なるサーバーレンダリング戦略があります:

このページでは、Server Componentsがどのように動作するのか、いつ使用するのか、そして異なるサーバーレンダリング戦略について説明します。

サーバーレンダリングの利点

サーバーでレンダリング作業を行うことにはいくつかの利点があります。

  • データ取得:Server Componentsを使用すると、データ取得をサーバー側に移行させ、データソースに近づけることができます。これにより、レンダリングに必要なデータを取得する時間を短縮し、クライアントが行うリクエストの数を減らしてパフォーマンスが向上します。
  • セキュリティ:サーバー上でトークンやAPIキーなどの機密データやロジックを保持し、クライアントに露出させるリスクを回避できます。
  • キャッシング:サーバーでレンダリングすることで、結果をキャッシュし、後のリクエストやユーザー間で再利用できます。これにより、各リクエストで行うレンダリングとデータ取得の量を減らし、パフォーマンス向上とコスト削減を実現できます。
  • パフォーマンス:Server Componentsを使用すると、基本からパフォーマンスを最適化するための追加ツールを使用できます。たとえば、完全にClient Componentsで構成されたアプリをベースにした場合、UIの非対話型部分をServer Componentsに移行すると、必要なクライアントサイドJavaScriptを減らすことができます。これは、インターネットが遅いユーザーや性能の低いデバイスを使用しているユーザーにとって有益です。ブラウザがダウンロード、解析、実行するクライアントサイドJavaScriptが少なくなります。
  • 初回ページロードとFirst Contentful Paint (FCP):サーバーでHTMLを生成し、ユーザーがページを即座に確認できるようにします。クライアントがページレンダリングに必要なJavaScriptをダウンロード、解析、実行するのを待つ必要はありません。
  • 検索エンジン最適化(SEO)とソーシャルネットワークでの共有性:レンダリングされたHTMLを使用して、検索エンジンのボットがページをインデックス化したり、ソーシャルネットワークのボットがページのソーシャルカードプレビューを生成したりできます。
  • ストリーミング:Server Componentsを使用することで、レンダリング作業をチャンクに分割し、それが準備でき次第クライアントにストリーミングできます。この方法を用いると、ページ全体がサーバーでレンダリングされるのを待たずに、ページの一部をユーザーが早く確認できるようになります。

Next.jsでServer Componentsを使用する

デフォルトでは、Next.jsはServer Componentsを使用します。これにより、追加の設定なしでサーバーレンダリングを自動的に実装することができ、必要に応じてClient Componentsを使用するオプションがあります。詳細はClient Componentsを参照してください。

Server Componentsはどのようにレンダリングされるのか?

サーバー側では、Next.jsはReactのAPIを使用してレンダリングをオーケストレーションします。レンダリング作業は、個別のルートセグメントやサスペンス境界に分割されます。

各チャンクは次の2段階でレンダリングされます:

  1. ReactがServer Componentsを**React Server Component Payload (RSC Payload)**という特別なデータ形式にレンダリングします。
  2. Next.jsがRSC PayloadとClient ComponentのJavaScript命令を使用して、サーバー上でHTMLをレンダリングします。

その後、クライアント側では以下の処理が行われます:

  1. HTMLを使用して、ルートの速い非対話型プレビューを即座に表示します。これは初回ページロード時のみです。
  2. React Server Components Payloadを使用して、Client ComponentとServer Componentの木を調整し、DOMを更新します。
  3. JavaScript命令を使用して、クライアントコンポーネントをハイドレートし、アプリケーションを対話型にします。

React Server Component Payload (RSC)とは?

RSC Payloadは、レンダリングされたReact Server Componentsツリーのコンパクトなバイナリ表現です。クライアント上のReactによりブラウザのDOMを更新するために使用されます。RSC Payloadには次の内容が含まれています:

  • Server Componentsのレンダリング結果
  • Client Componentsがレンダリングされるべき場所のプレースホルダーとそのJavaScriptファイルへの参照
  • Server ComponentからClient Componentに渡されるprop

サーバーレンダリング戦略

サーバーレンダリングには、静的、動的、ストリーミングの3つのサブセットがあります。

静的レンダリング (デフォルト)

静的レンダリングでは、ルートがビルド時またはデータの再検証後にバックグラウンドでレンダリングされます。その結果はキャッシュされ、コンテンツ配信ネットワーク (CDN)にプッシュすることができます。この最適化により、レンダリング作業の結果をユーザーやサーバーリクエスト間で共有できます。

静的レンダリングは、ルートにユーザーごとにパーソナライズされていないデータがあり、ビルド時に判明している場合に役立ちます。たとえば、静的なブログ記事や商品ページです。

動的レンダリング

動的レンダリングでは、ルートが各ユーザーに対してリクエスト時にレンダリングされます。

動的レンダリングは、ルートにユーザーごとにパーソナライズされたデータや、cookieまたはURLの検索パラメータなど、リクエスト時にしかわからない情報がある場合に役立ちます。

キャッシュされたデータを伴う動的ルート

ほとんどのウェブサイトでは、ルートは完全に静的でも完全に動的でもなく、スペクトラム上にあります。たとえば、定期的に再検証されるキャッシュされた製品データを使用するeコマースページがありながら、キャッシュされていないパーソナライズされた顧客データがあります。

Next.jsでは、キャッシュされたデータとキャッシュされていないデータの両方を持つ動的にレンダリングされたルートを持つことができます。これは、RSC Payloadとデータが別々にキャッシュされるためです。これにより、全てのデータをリクエスト時に取得する際のパフォーマンスへの影響を心配せずに、動的レンダリングのオプションを選ぶことができます。

フルルートキャッシュデータキャッシュについて詳しく学んでください。

動的レンダリングへの切り替え

レンダリング中に動的APIまたはキャッシュされていないデータ要求が発見された場合、Next.jsはルート全体を動的にレンダリングするように切り替えます。この表は、動的APIとデータキャッシングがルートが静的にあるいは動的にレンダリングされるかを示しています:

動的APIデータルート
いいえキャッシュ静的にレンダリング
はいキャッシュ動的にレンダリング
いいえ非キャッシュ動的にレンダリング
はい非キャッシュ動的にレンダリング

上記の表では、ルートが完全に静的であるためには、すべてのデータがキャッシュされている必要があります。ただし、キャッシュされたデータ取得とキャッシュされていないデータ取得を利用する動的にレンダリングされたルートを持つことができます。

開発者として、Next.jsは使用されるフィーチャーとAPIに基づいて各ルートに最適なレンダリング戦略を自動的に選択するため、静的と動的レンダリングの選択を行う必要はありません。その代わりに、いつキャッシュするか、または特定のデータを再検証するかを選択し、UIの一部をストリーミングすることを選択できます。

動的API

動的APIは、プリレンダリング中には事前に把握できず、リクエスト時にのみわかる情報に依存しています。これらのAPIのいずれかを使用すると、開発者の意図を示し、リクエスト時にルート全体を動的レンダリングに適応させます。これらのAPIには次のものが含まれます:

ストリーミング

ストリーミング中にルートセグメントが並列化され、個別のチャンクのデータ取得、レンダリング、ハイドレーションが行われている図。ストリーミング中にルートセグメントが並列化され、個別のチャンクのデータ取得、レンダリング、ハイドレーションが行われている図。

ストリーミングにより、サーバーからUIを段階的にレンダリングできます。作業はチャンクに分割され、それが準備でき次第クライアントにストリーミングされます。これにより、ユーザーはコンテンツ全体がレンダリングされる前にページの一部をすぐに見ることができます。

クライアントで部分的にレンダリングされたページで、ストリーミング中のチャンクのロード中のUIが表示される図。クライアントで部分的にレンダリングされたページで、ストリーミング中のチャンクのロード中のUIが表示される図。

ストリーミングはデフォルトでNext.js App Routerに組み込まれており、初期ページの読み込みパフォーマンスおよび、レンダリング全体を妨げるような遅いデータ取得に依存するUIの改善に役立ちます。たとえば、商品ページのレビューが該当します。

loading.jsを使用してルートセグメントをストリーミングすることや、React Suspenseを使用してUIコンポーネントと共にストリーミングを開始できます。詳しくはLoading UI and Streamingセクションを参照してください。