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が少なくなるためです。
- 初期ページロードとFirst Contentful Paint (FCP): サーバー上でHTMLを生成することで、クライアントがページをレンダリングするために必要なJavaScriptをダウンロード、解析、実行するのを待たずに、ユーザーがページをすぐに表示できるようにします。
- 検索エンジン最適化とソーシャルネットワークの共有性: レンダリングされたHTMLは、検索エンジンのボットがページをインデックス化し、ソーシャルネットワークのボットがページのソーシャルカードプレビューを生成するために使用できます。
- ストリーミング: Server Componentsを使用すると、レンダリング作業をチャンクに分割し、準備ができたらクライアントにストリーミングすることができます。これにより、ユーザーはページ全体がサーバーでレンダリングされるのを待たずに、ページの一部を早く見ることができます。
Next.jsでのServer Componentsの使用
デフォルトで、Next.jsはServer Componentsを使用します。これにより、追加の設定なしでサーバーレンダリングを自動的に実装でき、必要に応じてClient Componentsを使用することができます。詳細はClient Componentsを参照してください。
Server Componentsはどのようにレンダリングされるのか?
サーバー上で、Next.jsはReactのAPIを使用してレンダリングを調整します。レンダリング作業は、個々のルートセグメントとSuspense Boundariesによってチャンクに分割されます。
各チャンクは2つのステップでレンダリングされます:
- ReactはServer Componentsを**React Server Component Payload (RSC Payload)**と呼ばれる特別なデータ形式にレンダリングします。
- Next.jsはRSC PayloadとClient ComponentのJavaScript命令を使用して、サーバー上でHTMLをレンダリングします。
次に、クライアント側で:
- HTMLは、ルートの高速な非インタラクティブなプレビューを即座に表示するために使用されます - これは初期ページロード時のみです。
- React Server Components Payloadは、ClientとServer Componentのtreeを調整し、DOMを更新するために使用されます。
- JavaScript命令は、Client Componentsをhydrateし、アプリケーションをインタラクティブにします。
React Server Component Payload (RSC)とは?
RSC Payloadは、レンダリングされたReact Server Components treeのコンパクトなバイナリ表現です。クライアント上のReactがブラウザのDOMを更新するために使用します。RSC Payloadには以下が含まれます:
- Server Componentsのレンダリング結果
- Client Componentsがレンダリングされるべき場所のプレースホルダーとそのJavaScriptファイルへの参照
- Server ComponentからClient Componentに渡されるprops
サーバーレンダリング戦略
サーバーレンダリングには、Static、Dynamic、Streamingの3つのサブセットがあります。
Static Rendering (デフォルト)
Static Renderingでは、ルートはビルド時またはデータ再検証後のバックグラウンドでレンダリングされます。結果はキャッシュされ、Content Delivery Network (CDN)にプッシュすることができます。この最適化により、レンダリング作業の結果をユーザー間やサーバーリクエスト間で共有できます。
Static renderingは、ユーザーに個別化されていないデータを持ち、ビルド時に既知であるルートに役立ちます。たとえば、静的なブログ投稿や製品ページです。
Dynamic Rendering
Dynamic Renderingでは、ルートは各ユーザーのリクエスト時にレンダリングされます。
Dynamic renderingは、ユーザーに個別化されたデータや、リクエスト時にのみ既知の情報(cookieやURLの検索パラメータなど)を持つルートに役立ちます。
キャッシュされたデータを持つ動的ルート
ほとんどのウェブサイトでは、ルートは完全に静的でも完全に動的でもありません - それはスペクトラムです。たとえば、一定間隔で再検証されるキャッシュされた製品データを使用するeコマースページがあり、キャッシュされていない個別化された顧客データも持つことができます。
Next.jsでは、キャッシュされたデータとキャッシュされていないデータの両方を持つ動的にレンダリングされたルートを持つことができます。これは、RSC Payloadとデータが別々にキャッシュされるためです。これにより、リクエスト時にすべてのデータをフェッチするパフォーマンスへの影響を心配することなく、動的レンダリングを選択できます。
full-route cacheとData Cacheについて詳しく学びましょう。
Dynamic Renderingへの切り替え
レンダリング中に、Dynamic APIまたは{ cache: 'no-store' }
のfetchオプションが発見された場合、Next.jsはルート全体を動的にレンダリングするように切り替えます。この表は、Dynamic APIとデータキャッシングがルートが静的または動的にレンダリングされるかどうかにどのように影響するかをまとめたものです:
Dynamic APIs | Data | Route |
---|---|---|
No | Cached | Statically Rendered |
Yes | Cached | Dynamically Rendered |
No | Not Cached | Dynamically Rendered |
Yes | Not Cached | Dynamically Rendered |
上記の表では、ルートが完全に静的であるためには、すべてのデータがキャッシュされている必要があります。ただし、キャッシュされたデータフェッチとキャッシュされていないデータフェッチの両方を使用する動的にレンダリングされたルートを持つことができます。
開発者としては、Next.jsが使用される機能とAPIに基づいて各ルートに最適なレンダリング戦略を自動的に選択するため、静的レンダリングと動的レンダリングのどちらかを選択する必要はありません。代わりに、キャッシュするタイミングや特定のデータを再検証するタイミングを選択し、UIの一部をストリーミングすることを選択できます。
Dynamic APIs
Dynamic APIsは、リクエスト時にのみ既知の情報(事前レンダリング中には既知でない)に依存します。これらのAPIのいずれかを使用すると、開発者の意図が示され、リクエスト時にルート全体が動的レンダリングに切り替わります。これらのAPIには以下が含まれます:
Streaming
ストリーミングを使用すると、サーバーからUIを段階的にレンダリングできます。作業はチャンクに分割され、準備ができたらクライアントにストリーミングされます。これにより、ユーザーはコンテンツ全体がレンダリングを完了する前に、ページの一部を即座に見ることができます。
ストリーミングはデフォルトでNext.jsのApp Routerに組み込まれています。これにより、初期ページロードのパフォーマンスが向上し、ルート全体のレンダリングをブロックする遅いデータフェッチに依存するUIも改善されます。たとえば、製品ページのレビューなどです。
loading.js
とUIコンポーネントを使用してルートセグメントのストリーミングを開始できます。React Suspenseを参照してください。Loading UI and Streamingセクションで詳細を確認できます。