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