プロンプトとコンテキスト
このページには、ナビゲーション、記事本文、おすすめ、コメント、パーソナライズされたアクションが含まれています。記事は素早く表示される必要があり、遅延しているモジュールが最初のバイト(TTFB)をブロックしたり、単一サービスの障害でページ全体をダウンさせたりしてはなりません。Suspenseを使用したストリーミングSSRを設計し、サーバーがどのようにシェルを送信し、バウンダリがどのように完了し、障害がどのようにデグレードされ、スクリプト読み込み後にクライアントがどのようにリカバリするかを説明してください。
Reactのドキュメントには、ストリーミングによってまずシェルとフォールバックを送信し、バウンダリの処理が完了するにつれてそれらを順次置換できると記載されています。この面接では、その仕組みをタイムアウト、エラー、キャッシュ、モニタリングの制御された動作へと落とし込めるかがテストされます。
面接官が評価するポイント
安定したシェルと非同期バウンダリ、リクエストの重複排除、バウンダリのタイムアウト、サーバーエラー、クライアントのリトライ、キャッシュのバリアント、キャンセル処理、アクセシビリティ、Core Web Vitalsを網羅してください。どのコンテンツを同期的(synchronous)にし、どのコンテンツを遅延可能にするかを明示してください。
質問すべき明確化のための質問
- ファーストスクリーンの目標はTTFB、LCP、インタラクションまでの時間のどれであり、それぞれの予算(バジェット)はどうなっていますか?
- 記事、おすすめ、コメント、パーソナライゼーションにはどのような可用性とプライバシーレベルが適用されますか?
- ページはCDNでキャッシュされますか?また、ユーザー、地域、実験(A/Bテスト)のバリアントは存在しますか?
- 低速モジュールの障害時、UIは空の状態、古いデータ、リトライのどれを表示すべきですか?
- クライアントのJavaScriptが失敗した場合に機能しなければならないコアパスはどれですか?
30秒での回答
「低速なデータに依存しないシェルを送信し、おすすめ、コメント、パーソナライゼーションを明確なバジェットを持つSuspenseバウンダリに分割します。各バウンダリにはサーバータイムアウト、監視可能なエラー、許容可能なフォールバックを設定し、障害が局所的に留まるようにします。クライアント側はハイドレーション後に制限付きのリトライとインタラクションを担当します。安全なパブリックフラグメントのみをキャッシュし、TTFB、LCP、INP、エラー、バウンダリのレイテンシを監視します。」
ステップごとの詳細解説
ステップ1:シェルとバウンダリを分割する
ルーティング、タイトル、記事の構造、主要なセマンティクスを同期的に完了させます。おすすめ、コメント、パーソナライゼーションは個別のバウンダリに配置します。バウンダリはリモート依存関係の単なる集まりではなく、ユーザーにとって理解可能な領域を表す必要があります。
shell: navigation + heading + article outline
boundary A: recommendations, budget 300 ms
boundary B: comments, budget 500 ms
boundary C: personalized actions, private and uncachedレイアウトシフトを防ぐために、各フォールバックで見出し、寸法、セマンティクスを維持してください。何が読み込まれているのかをユーザーが理解できなくなるほどページを細分化しすぎないでください。
ステップ2:ストリーミングとキャンセル処理を構築する
フレームワークのストリーミングサーバーレンダリングAPIを使用して、シェルが最初に応答に入り、データが解決するにつれてバウンダリが続くようにします。リクエストの期限を設定し、タイムアウト後はリモート呼び出しをキャンセルして許容可能なフォールバックを出力します。クライアントは、すでにキャンセルされたサーパータスクを待つべきではありません。
バウンダリの開始、完了、タイムアウト、エラーイベントを記録します。クライアントが切断された場合は、放棄されたページがデータベースやおすすめエンジンのキャパシティを消費しないよう、未完了のフェッチをキャンセルします。
ステップ3:サーバーとクライアントのエラーを処理する
サーバーバウンダリ内のエラーは、シェルと完了済みの兄弟要素を維持したまま、そのバウンダリのフォールバックへと解決されるべきです。運用者向けに安定したバウンダリ識別子とリクエストトレースIDを付与し、ユーザー向けの文言にはセクションが一時的に利用できないことのみを示します。
クライアントコードが読み込まれた後は、対象のバウンダリに対してバックオフに基づく制限付きのリトライを許可します。リトライには試行回数の上限、べき等性の条件、キャンセル処理が必要です。クライアントスクリプトが失敗した場合でも、記事のテキスト、リンク、コアフォームは引き続き使用可能である必要があります。
ステップ4:キャッシュバウンダリを定義する
公開記事コンテンツとユーザーに依存しないモジュールは、ルート、言語、地域、コンテンツバージョンに応じたキーでキャッシュします。パーソナライズされたバウンダリをパブリックなHTMLキャッシュに入れてはなりません。実験バリアントはキーに明示するか、エッジで分離する必要があります。
キャッシュヒットによって元の古いデータが隠蔽されてはなりません。フラグメントごとに生成日時、有効期限、バージョンを記録し、一貫した鮮度ポリシーを使用します。最終的に連結されたストリーム全体のキャッシュには注意が必要であり、通常は安全なフラグメント単位の方が優れたキャッシュバウンダリとなります。
ステップ5:アクセシビリティとレイアウトの安定性を維持する
フォールバックと最終コンテンツで、同じセマンティックな見出し、ランドマーク、寸法の制約を維持します。コンテンツの置換によって、キーボードフォーカスが不可視のノードに移動してはなりません。動的な領域には、ページ全体を繰り返し読み上げることなく適切なステータス通知が必要です。
画像やメディアの寸法を確保し、スケルトンのジオメトリを安定させてCLSを監視します。記事の主要コンテンツを早期に表示されるバウンダリ内に保持し、LCP要素を制御不能なロングテールリクエストの配下に置かないでください。
ステップ6:リリースとオブザーバビリティのゲートを追加する
リリース前テストでは、遅延する依存関係、500エラー、切断、クライアントスクリプトの障害、キャッシュ汚染、キャンセル処理を網羅します。本番環境では、TTFB、LCP、INP、バウンダリのp50/p95、タイムアウト率、フォールバック率、リトライ成功率をルート、バウンダリ、依存関係ごとに測定します。
カナリアリリースの間は、高リスクなパーソナライゼーションを公開する前にシェルとクリティカルなバウンダリを観察します。エラーやテールレイテンシが閾値を超えた場合は、トラフィックを拡大するのではなく、バウンダリの構成や静的フォールバックをロールバックします。
優れた回答例
私ならまずファーストスクリーンのバジェットと可用性レベルを定義し、記事のシェル、おすすめ、コメント、パーソナライゼーションを独立したSuspenseバウンダリに分割します。各バウンダリにはタイムアウト、フォールバック、キャンセルパス、トレースIDを付与し、障害が局所化されるようにします。パブリックフラグメントには安全なキャッシュディメンションを使用し、パーソナライゼーションが共有キャッシュに入ることは決してありません。切断やスクリプトの障害をテストし、LCP、INP、CLS、バウンダリのp95、フォールバック率を監視します。
よくある間違い
- ページ全体を1つのバウンダリで囲む → 最も遅い依存関係がすべてをブロックする → ユーザーが理解できる領域ごとに分割する。
- フォールバックに固定寸法を与えない → 置換時にCLSが発生する → スペースを確保し、セマンティクスを維持する。
- パーソナライズされたHTMLをパブリックキャッシュに置く → ユーザーデータが漏洩する可能性がある → プライベートなフラグメントを分離し、安全なキーディメンションを含める。
- サーバータイムアウト後に無限にリトライする → 依存関係への負荷が増幅される → バジェット、バックオフ、上限、キャンセルを活用する。
- 成功ケースのみをテストする → 切断やスクリプトの失敗でページが使用不能になる → エラー、キャンセル、スクリプト無効時のデグラデーションをテストする。
フォローアップ質問と回答
フォローアップ1:バウンダリは多ければ多いほど良いですか?
いいえ。バウンダリは独立したユーザー領域と障害ドメインに対応させるべきです。細かすぎるバウンダリはフォールバックのノイズ、監視コスト、キャッシュバリアントを増加させます。一方、粗すぎるバウンダリはブロッキングドメインを拡大させます。
フォローアップ2:1つのエラーでストリーム全体が終了するのをどう防ぎますか?
リカバリ処理をバウンダリのサーバーおよびクライアントパス内に留め、すでに送信されたシェルを維持し、各バウンダリに安定したフォールバックを提供します。レスポンスの一部がすでに送信された後の障害をテストします。
フォローアップ3:設計が機能していることをどのメトリクスで証明しますか?
TTFB、LCP、INP、CLS、バウンダリのp95、タイムアウト率、フォールバック率、リトライ成功率を総合的に追跡します。平均応答時間だけではテールレイテンシや局所的な障害を見逃してしまいます。
フォローアップ4:実験やユーザーデータのキャッシュ漏洩をどのように防ぎますか?
キーにユーザー、実験、地域、言語、コンテンツバージョンの安全ディメンションを含めます。安全性が証明できないフラグメントはパブリックキャッシュから除外した上で、ユーザー間リプレイテストにより分離を検証します。