エッジからのストリーミングSSR
ReadableStreamを使ってReactのHTML出力をストリーミングし、ブラウザーが意味のあるコンテンツをすぐに描画できるようにします。
「エッジからのストリーミングSSR」はCoddyKit上の無料React Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
ストリーミングの利点
サーバーが HTML をストリーミングすると、ブラウザーはドキュメント全体を待つのではなく、チャンク単位でコンテンツを受信してレンダリングします。そのため、ヘッダー、ナビゲーション、ヒーローセクションなど、ページの表示可能な部分をユーザーが見たり操作したりしている間に、データに依存する遅いセクションの読み込みを続けられます。
bootstrapScripts と renderToReadableStream
renderToReadableStream に bootstrapScripts を渡すと、クライアント側の JS バンドルの場所を React に伝えられます。React はストリームの末尾に script タグを挿入するため、ブラウザーはバンドルを読み込んで hydrateRoot を呼び出します。これにより、各セクションのストリーミングが完了するたびにページがインタラクティブになります。
ツリー内の Suspense 境界
React のストリーミングは、コンポーネントツリーを独立してストリーミングできるセクションに分割する Suspense 境界に依存しています。データを待機している(throw された Promise を介して待機している)Suspense 境界内のコンポーネントは、まずプレースホルダーとしてストリーミングされ、その後データの準備が整うと実際のコンテンツがストリーミングされます。
onShellReady:ストリーミングを開始するタイミング
onShellReady callback は、Suspense 境界の外側にあるすべての要素、つまり suspend されていない HTML シェルの準備が整ったときに呼び出されます。これは、HTTP ステータスコードとレスポンスヘッダーを設定し、その後 pipe(res) を呼び出すか ReadableStream の読み取りを開始する適切なタイミングです。
ステータスコードを先に設定する理由
HTTP ステータスコードとヘッダーは、レスポンスボディが始まる前に送信する必要があります。ストリーミングは onShellReady で開始されるため、エラー処理(ステータスを 500 に設定する、リダイレクトするなど)はシェルのストリーミング開始前に行わなければなりません。ストリーミングが始まると、ステータスコードは変更できなくなります。
エラー処理:onShellError
onShellError は、シェルの準備が整う前に致命的なエラーが発生したときに呼び出されます。たとえば、Suspense 境界の外側にある最上位コンポーネントでエラーが発生した場合です。この場合、シェルはストリーミングされないため、静的なエラーページを返すか、エラールートにリダイレクトしてください。
エラー処理:onError
onError は、Suspense 境界内で回復可能なエラーが発生したときに呼び出されます。React はページの残りの部分を引き続きストリーミングでき、エラーが発生した境界ではエラー時のフォールバック UI がレンダリングされます。onError はロギングに使用し、ストリームを中断せずにエラーを observability platform に記録してください。
段階的エンハンスメントとタイムアウト
If a Suspense boundary's data takes too long, stream the shell anyway and let the boundary hydrate on the client. Implement a timeout: after 5 seconds, call abort() on the stream if the boundary hasn't resolved, and the client will fetch the data itself via useEffect.
Cloudflare Workersのストリーミングの仕組み
WorkersランタイムはReadableStreamをResponseのボディとして直接渡します。Cloudflareのインフラストラクチャは、ドキュメント全体をバッファリングせず、Reactが生成した各チャンクをユーザーのブラウザーへ転送します。これにより、リクエストが到着してから数ミリ秒以内に、HTMLの最初のバイトがエッジPoPから送信されます。
Abort: 長時間のストリームを制御する
renderToReadableStreamは、abort用の関数を返します。リクエストがキャンセルされた場合(ユーザーが別のページへ移動した場合)は、abort()を呼び出すことで、Reactがレンダリングとデータ処理を続けるのを停止できます。これにより、孤立したリクエストに対する無駄な計算を防ぎ、WorkerのCPU使用量を一定範囲に抑えられます。
エンドツーエンドのレイテンシプロファイル
エッジストリーミングを利用した場合、レイテンシの全体像は次のようになります。5ms(最寄りのPoPへのリクエスト) + 2ms(Workerのコールドスタート) + 8ms(シェルのレンダリング) = 最初のバイトまで15msです。ユーザーのブラウザーはシェルからLCP要素をレンダリングし、その間もページの残りの部分はバックグラウンドでストリーミングされ続けます。
onShellReadyのタイミング
ストリーミングSSRでは、onShellReadyコールバックは正確にはいつ呼び出されますか?
レッスンのまとめ
エッジからのストリーミングSSRでは、HTMLをチャンク単位で配信することで、シェルを即座に送信し、FCPとLCPを改善できます。Suspense境界によってツリーを独立してストリーミングできるセクションに分割できます。onShellReadyはパイプ処理を開始する合図です。呼び出す前にステータスコードを設定してください。致命的な失敗はonShellErrorで、回復可能なエラーはonErrorで処理し、キャンセルされたリクエストに対する無駄な処理はabort()で防ぎます。
よくある質問
「エッジからのストリーミングSSR」レッスンは無料ですか?
はい。「エッジからのストリーミングSSR」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「エッジからのストリーミングSSR」で何を学びますか?
ReadableStreamを使ってReactのHTML出力をストリーミングし、ブラウザーが意味のあるコンテンツをすぐに描画できるようにします。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「エッジからのストリーミングSSR」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。