サーバーコンポーネント
Reactサーバーコンポーネントを使用すると、サーバーでレンダリングされ、オプションでキャッシュされるUIを記述できます。Next.jsでは、レンダリング作業はルーティングセグメントによってさらに分割され、ストリーミングと部分レンダリングを可能にします。サーバーレンダリングには3つの異なる戦略があります。
このページでは、サーバーコンポーネントがどのように機能するか、いつ使用すべきか、およびさまざまなサーバーレンダリング戦略について説明します。
サーバーレンダリングの利点
サーバーでレンダリング作業を行うことには、いくつかの利点があります。
- データフェッチ: サーバーコンポーネントを使用すると、データフェッチをサーバーに移動させ、データソースに近づけることができます。これにより、レンダリングに必要なデータをフェッチする時間の短縮と、クライアントが行うリクエスト数の削減により、パフォーマンスが向上します。
- セキュリティ: サーバーコンポーネントを使用すると、トークンやAPIキーなどの機密データやロジックをクライアントに公開するリスクなく、サーバー上に保持できます。
- キャッシュ: サーバーでレンダリングすることにより、その結果をキャッシュし、後続のリクエストや複数のユーザー間で再利用できます。これにより、各リクエストで行われるレンダリングとデータフェッチの量を減らすことで、パフォーマンスが向上し、コストが削減されます。
- パフォーマンス: サーバーコンポーネントは、ベースラインからパフォーマンスを最適化するための追加ツールを提供します。たとえば、完全にクライアントコンポーネントで構成されたアプリから始める場合、UIの非インタラクティブな部分をサーバーコンポーネントに移動すると、必要なクライアントサイドJavaScriptの量を減らすことができます。これは、ブラウザがダウンロード、解析、実行するクライアントサイドJavaScriptが少なくなるため、インターネット速度が遅いユーザーや性能の低いデバイスを使用しているユーザーにとって有益です。
- 初期ページロードとFirst Contentful Paint (FCP): サーバーでは、ユーザーがページをレンダリングするために必要なJavaScriptをダウンロード、解析、実行するのを待つことなく、すぐにページを表示できるようにHTMLを生成できます。
- 検索エンジン最適化とソーシャルネットワークでの共有性: レンダリングされたHTMLは、検索エンジンボットによってページのインデックス作成に、ソーシャルネットワークボットによってページのソーシャルカードプレビューの生成に利用できます。
- ストリーミング: サーバーコンポーネントを使用すると、レンダリング作業をチャンクに分割し、準備ができたものからクライアントにストリーミングできます。これにより、ユーザーはページ全体がサーバーでレンダリングされるのを待つことなく、ページの一部をより早く見ることができます。
Next.jsにおけるサーバーコンポーネントの使用
デフォルトでは、Next.jsはサーバーコンポーネントを使用します。これにより、追加の設定なしでサーバーレンダリングを自動的に実装でき、必要に応じてクライアントコンポーネントの使用を選択できます。クライアントコンポーネントを参照してください。
サーバーコンポーネントはどのようにレンダリングされるか?
サーバーでは、Next.jsはReactのAPIを使用してレンダリングを調整します。レンダリング作業は、個々のルートセグメントとSuspense Boundariesによってチャンクに分割されます。
各チャンクは2つのステップでレンダリングされます。
- Reactはサーバーコンポーネントを、React Server Component Payload (RSCペイロード) と呼ばれる特殊なデータ形式にレンダリングします。
- Next.jsはRSCペイロードとクライアントコンポーネントのJavaScript命令を使用して、サーバー上でHTMLをレンダリングします。
次に、クライアント側では
- HTMLは、ルートの高速で非インタラクティブなプレビューをすぐに表示するために使用されます。これは初期ページロードのみに適用されます。
- Reactサーバーコンポーネントペイロードは、クライアントとサーバーのコンポーネントツリーを調和させ、DOMを更新するために使用されます。
- JavaScript命令は、クライアントコンポーネントをハイドレートし、アプリケーションをインタラクティブにするために使用されます。
React Server Component Payload (RSC) とは?
RSCペイロードは、レンダリングされたReactサーバーコンポーネントツリーのコンパクトなバイナリ表現です。これはクライアント側のReactによってブラウザのDOMを更新するために使用されます。RSCペイロードには以下が含まれます。
- サーバーコンポーネントのレンダリング結果
- クライアントコンポーネントがレンダリングされるべき場所のプレースホルダーと、それらのJavaScriptファイルへの参照
- サーバーコンポーネントからクライアントコンポーネントに渡されるプロパティ
サーバーレンダリング戦略
サーバーレンダリングには、静的、動的、ストリーミングの3つのサブセットがあります。
静的レンダリング (デフォルト)
静的レンダリングでは、ルートは**ビルド時**にレンダリングされるか、データ再検証後にバックグラウンドでレンダリングされます。その結果はキャッシュされ、コンテンツデリバリーネットワーク (CDN)にプッシュできます。この最適化により、レンダリング作業の結果をユーザーとサーバーリクエスト間で共有できます。
静的レンダリングは、ルートにユーザーに個別化されていないデータがあり、静的なブログ投稿や製品ページのようにビルド時に判明するデータがある場合に役立ちます。
動的レンダリング
動的レンダリングでは、ルートは**リクエスト時**に各ユーザー向けにレンダリングされます。
動的レンダリングは、ルートにユーザーに個別化されたデータがある場合や、クッキーやURLの検索パラメータのようにリクエスト時にのみ判明する情報がある場合に役立ちます。
キャッシュデータを使用した動的ルート
ほとんどのウェブサイトでは、ルートは完全に静的でも完全に動的でもなく、その中間です。たとえば、定期的に再検証されるキャッシュされた製品データを使用するeコマースページがありつつも、キャッシュされていない個別化された顧客データも持つことができます。
Next.jsでは、キャッシュされたデータとキャッシュされていないデータの両方を持つ動的にレンダリングされたルートを持つことができます。これは、RSCペイロードとデータが別々にキャッシュされるためです。これにより、リクエスト時にすべてのデータをフェッチすることによるパフォーマンスへの影響を心配することなく、動的レンダリングを選択できます。
フルルートキャッシュとデータキャッシュについて詳しく学びましょう。
動的レンダリングへの切り替え
レンダリング中に動的API、または{ cache: 'no-store' }
のfetchオプションが検出された場合、Next.jsはルート全体を動的にレンダリングするように切り替えます。この表は、動的APIとデータキャッシュがルートが静的にレンダリングされるか動的にレンダリングされるかにどのように影響するかをまとめたものです。
動的API | データ | ルート |
---|---|---|
なし | キャッシュ済み | 静的レンダリング |
あり | キャッシュ済み | 動的レンダリング |
なし | キャッシュなし | 動的レンダリング |
あり | キャッシュなし | 動的レンダリング |
上記の表では、ルートが完全に静的であるためには、すべてのデータがキャッシュされている必要があります。ただし、キャッシュされたデータ取得とキャッシュされていないデータ取得の両方を使用する動的にレンダリングされたルートを持つこともできます。
開発者は静的レンダリングと動的レンダリングの間で選択する必要はありません。Next.jsは使用されている機能やAPIに基づいて各ルートに最適なレンダリング戦略を自動的に選択します。代わりに、特定のデータをキャッシュするか再検証するかを選択し、UIの一部をストリーミングすることを選択できます。
動的API
動的APIは、リクエスト時にのみ(プリレンダリング時に事前には)判明する情報に依存します。これらのAPIのいずれかを使用すると、開発者の意図が示され、ルート全体がリクエスト時に動的レンダリングにオプトインされます。これらのAPIには以下が含まれます。
ストリーミング

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

ストリーミングはNext.js App Routerにデフォルトで組み込まれています。これにより、初期ページロードのパフォーマンスと、ルート全体のレンダリングをブロックする可能性のある遅いデータフェッチに依存するUIの両方が向上します。たとえば、製品ページのレビューなどです。
loading.js
を使用してルートセグメントのストリーミングを開始し、React Suspenseを使用してUIコンポーネントをストリーミングできます。詳細については、UIの読み込みとストリーミングセクションを参照してください。
この情報は役に立ちましたか?