代表的な面接トピック

フロントエンド面接:CSR、SSR、SSG、ISR をどのように選択するか?

フロントエンド難しい
Offer.cc 編集チーム公開日 更新日

質問

Next.js 16 のコマースプラットフォームに、週次で更新される 20,000 件の公開ガイド、100 万件の商品ページ、リアルタイムの検索結果、およびログインユーザーの注文ページがあります。商品の説明文は 5 分間の古さが許容されますが、価格と在庫は購入手続き(チェックアウト)の前にリアルタイムで確認する必要があります。各ルートに対して CSR、SSR、SSG、または ISR を選択し、SEO、初回配信、サーバー負荷、キャッシュ無効化、障害時の挙動、および検証方法について説明してください。

設問と適用シナリオ

Next.js 16 のコマースプラットフォームには、4 つのページファミリがあります。

  • /guides/[slug]: 週次で編集され、検索エンジンが本文を確実に検出できる必要がある 20,000 件の公開ガイド。
  • /products/[id]: 説明文や画像は最大 5 分間古くても許容されるが、価格と在庫はチェックアウト前にリアルタイムで確認する必要がある 100 万件の公開商品ページ。
  • /search?q=: クエリ、フィルター、現在のカタログ状態によって変化する結果。初回表示は共有可能であるべきだが、すべてのクエリの組み合わせをインデックスする必要はない。
  • /account/orders: ログインユーザーごとに異なり、共有キャッシュにも検索インデックスにも登録してはならないプライベートページ。

チームは、公開ページの発見可能性やインタラクティブなページの応答性を損なうことなく、オリジンでのレンダリングを削減したいと考えています。候補者は、各ルートファミリに対して主要なレンダリング戦略を選択し、どの領域で異なる戦略を混在させることができるかを述べる必要があります。回答には、鮮度の境界、無効化トリガー、障害時の出力、および本番環境での証明を定義しなければなりません。

2026 年の公開フロントエンド面接ガイドには、特定のページに対するレンダリング戦略の選択や ISR と SSR の判断が明確に挙げられています。別のフロントエンド問題バンクにも、CSR、SSR、SSG、ISR の専用比較があります。多くの検索結果は 4 行のメリット・デメリット表で終わっています。無効化、クリティカルなフィールドのライブ検証、外部 CDN、障害セマンティクスを組み合わせているものはほとんどありません。この設問は、その本番における意思決定レイヤーを追加するものです。

面接官が評価するポイント

第一に、候補者が略語を選択する前に要件を定義しているかどうかです。レンダリング場所自体は目的ではありません。公開インデックス可能性、初期コンテンツ、鮮度、パーソナライズ、トラフィック、ページ数、インタラクションコスト、障害時の挙動が入力情報となります。「SSR は SEO に良い」という理由だけでは、注文ページや 100 万ページのカタログを決定することはできません。

第二に、各戦略がどこにコストをかけるかを理解しているかどうかです。

戦略HTML が生成されるタイミング主な利点主なコスト
CSRブラウザで JavaScript が実行された後プライベートで高度にインタラクティブな状態を直接更新初期コンテンツはスクリプトとデータリクエストに依存。クライアントコストが高い
SSRリクエストごとにサーバー上リクエストごとに最新またはパーソナライズされた HTMLレイテンシと可用性はレンダリングとアップストリームに依存。トラフィックに応じてコンピュートが増加
SSGビルド時静的ファイルはキャッシュが容易でオリジンの負荷を軽減リリースがページ数と密結合。更新には通常再生成が必要
ISR最初は静的、その後時間またはイベントで再生成インクリメンタルな更新を伴う静的配信明示的なステイルネス(古さ)、無効化の伝播、再生成失敗時のセマンティクス

第三に、ハイブリッド構成を特定できるかどうかです。商品ページでは、インデックス可能な説明文に ISR を使用し、現在の配送オプションをクライアントで取得し、チェックアウトサービスで価格と在庫を再検証することができます。ISR を選択したからといって、すべてのフィールドを古いままで安全に配信できるわけではありません。SSR を選択したからといって、クライアントの JavaScript やハイドレーションが不要になるわけでもありません。

第四に、その選択をテスト可能な契約に変換できるかどうかです。優れた回答では、コンテンツがどれくらい古くなる可能性があるか、誰が無効化するか、再生成が失敗したときに何が表示されるか、キャッシュキーにユーザーや地域が含まれているか、実際のブラウザがダウンロードする JavaScript の量はどれくらいかを明記します。また、ビルド、ランタイム、キャッシュ、ビジネスの正確性のメトリクスを提示します。

回答前に明確にすべき質問

  • そのページは公開されており、インデックスされることを意図していますか? 公開される本文テキスト、タイトル、canonical、ステータスは、初回のレスポンスに含まれていることが望ましいです。プライベートな注文には、認証、共有キャッシュの禁止、および明示的な noindex ポリシーが必要です。
  • 「リアルタイム」とはどれくらいの速さですか? 説明文は 5 分前のものでも構いませんが、価格と在庫は支払いの約束に影響します。これらのフィールドに同じキャッシュ SLA を継承させることはできません。
  • どのディメンションによってコンテンツが変化しますか? ロケール、地域、通貨、認証、テストグループによってキャッシュキーが変わる可能性があります。ディメンションが不足すると誤ったデータやプライベートデータが配信されるリスクがあり、多すぎるとヒット率が低下します。
  • ページ数と更新の分布はどのようになっていますか? リリースごとに 100 万件の URL をビルドするのは非現実的です。95% がロングテールページである場合は、人気のあるパスを事前ビルドし、残りは初回アクセス時に生成します。
  • 公開イベントは信頼できますか? CMS やカタログはエンティティ ID を発行できますか?イベントが失われる可能性がある場合は、補償策として時間ベースの有効期限、リコンシリエーション(整合性確認)、または手動無効化を追加します。
  • キャッシュはどのようにデプロイされていますか? 単一プロセス、マルチコンテナ、マネージドプラットフォーム、外部 CDN では無効化の伝播方法が異なります。Next.js のサーバーキャッシュをパージしても、別の CDN コピーがそのまま残る場合があります。
  • 障害発生時、誤ったコンテンツよりも古いコンテンツの方が安全ですか? 最後に成功したガイドを配信することは通常合理的です。価格、在庫、注文ステータスは、信頼できる権威あるサービスによって確認されなければなりません。
  • 成功判定の基準(Success Gate)は何ですか? インデックス可能なコンテンツの完全性、TTFB/LCP/INP、ヒット率、再生成遅延、コンテンツの経過時間、オリジンレンダリング QPS、ビルド時間、エラー率、チェックアウト競合率を定義します。

30秒の回答フレームワーク

「私は、公開性、リクエストごとの変動、鮮度、ページ数によってルートを分割します。ガイドは主に SSG で、公開時にパスごとに無効化します。商品詳細は、低コストでインデックス可能な本文のために ISR を使用し、カタログイベントに加えて 5 分のタイムフォールバックを設けます。価格と在庫はクライアントで更新し、チェックアウト時に再度確認します。検索はクエリごとの SSR とし、ユーザーディメンションを含むレスポンスは共有しません。プライベートな注文は認証済みサーバーシェルと CSR データ更新を使用します。本番ビルドでキャッシュの挙動を検証し、単一の Lighthouse スコアを信用するのではなく、コンテンツの経過時間、ヒット率、TTFB、LCP、JavaScript サイズ、再生成失敗、ビジネス競合を監視します。」

ステップごとの詳細解説

ステップ 1: 1 つの決定マトリクスを使用してルートごとの主要戦略を選択する

フレームワークの API から始めるのではなく、すべてのページファミリを同じマトリクスに通します。

ルート主要戦略理由混在領域
ガイドSSG + イベント再生成公開、低頻度の編集、全ユーザーで同一の本文公開後にパスを無効化。定期的にリコンシリエーションを実行
商品詳細ISR膨大な公開 URL。本文は短時間の古さを許容リアルタイム価格/在庫、チェックアウト時のサーバー再確認
検索結果SSR膨大なクエリ空間。結果はリクエストごとに変化ブラウザがフィルターと後続のインタラクションを担当
プライベート注文主に CSRユーザーごと、非インデックス、インタラクション重視サーバーは認証済みシェルとスケルトンを出力可能

「SSG に公開時の無効化を組み合わせる」方法は、ランタイムでのインクリメンタルな再生成を利用しますが、その主要なコンテンツモデルは事前レンダリングされた静的ページのままです。これは 20,000 件のガイドへのすべてのリクエストに対して SSR を行うよりも安価であり、誤字修正のためにサイト全体を再ビルドするよりもピンポイントです。最初はすべてのガイドをビルドできますが、セットが増加した場合は、人気のあるパスを事前ビルドし、残りは初回リクエスト時に生成します。

ISR は、本文が公開されており、繰り返し閲覧され、一時的に古くても許容されるため、商品詳細に適しています。5 分の再検証設定は、あらゆる状況で厳密な 5 分の最大値になるわけではありません。間隔後の最初のリクエストは、バックグラウンドでの再生成が開始される間、依然として古い HTML を受け取る可能性があります。トラフィックの少ないページはトリガーが遅れる場合があり、再生成に失敗すると古いバージョンの寿命が延びます。公開を即座に反映させる必要がある場合は、書き込み成功後に商品 ID で無効化し、時間ウィンドウは補償策としてのみ維持します。

検索クエリの空間は大きすぎて事前ビルドできません。SSR を使用すれば、クエリと整合したコンテンツと実際のステータスを初回レスポンスに含めることができます。キャッシュキーには、結果を変更するすべての公開パラメータを含める必要があります。認証やパーソナライズされた価格に関わるレスポンスは、プライベートにするかキャッシュ不可にする必要があります。初回表示後のフィルター、ページネーション、入力はクライアントが引き継ぎます。

注文ページは、公開インデックス可能な HTML から何の恩恵も受けません。サーバーが認証済みシェルを確立し、CSR がユーザー API からリストとライブステータスをロードします。そのレスポンスは共有キャッシュに入ってはなりません。CSR はレンダリングの選択肢であり、認証と認可は依然としてサーバーの責務です。

ステップ 2: ISR を鮮度と無効化の契約として表現する

商品ルートには 2 つの契約が必要です。

text
Cacheable body: name, description, images, category
  Event invalidation: after product:{id} updates successfully
  Time fallback: 300 seconds
  Failure semantics: serve the last successful version and alert

Critical live fields: price, inventory, delivery eligibility
  Page display: refresh from the authority and show update time
  Checkout submission: recompute on the server and confirm changes

Next.js の ISR ガイドには、間隔後の最初のリクエストは、バックグラウンドで再生成が実行されている間に古いコンテンツを受け取る可能性があると記載されています。その後のリクエストは、成功後に新しいバージョンを受け取ります。再生成で例外がスローされた場合、最後に成功したバージョンがキャッシュされたままになり、別のリクエストが再試行します。コンテンツの経過時間を監視してください。設定値はビジネス SLA が満たされていることの証明にはなりません。

Next.js 16 では、revalidateTag(tag, "max") は stale-while-revalidate を使用し、わずかな遅延を許容する記事、カタログ、または商品の本文に適しています。ユーザーが自身の書き込みを即座に読み取る必要がある場合、Server Action 内の updateTag が read-your-writes(自分の書き込みの即時読み取り)セマンティクスを提供します。これらは交換可能な「キャッシュクリア」ボタンではありません。イベントソース、許容される古さ、呼び出し場所によって、適切な操作が決まります。

伝播チェーンも描いてください。ブラウザ、CDN、Next.js ルートキャッシュ、データキャッシュ、アップストリームサービスは、それぞれ TTL を持つことができます。公式 CDN ガイドは、Next.js でのパスまたはタグの無効化が、個別にキャッシュされた CDN コピーを自動的にパージしないことを警告しています。外部 CDN が追加されている場合は、一致する HTML およびデータバリアントもパージするか、その TTL が同じ鮮度契約を満たすようにします。マルチインスタンスのセルフホスティングでも、1 つのインスタンスだけが古いままにならないように、共有キャッシュまたは同期されたタグ状態が必要です。

ステップ 3: SEO、インタラクション、障害境界を個別に処理する

Google は JavaScript を実行してレンダリングされた HTML をインデックスできますが、レンダリングはキューに入り、他のボットは JavaScript を実行しない場合があります。公開ガイドと商品本文では、可視テキスト、タイトル、canonical、構造化データ、正しいステータスを初期 HTML に含める必要があります。空の 200 シェルを返して、クライアントが存在しない商品を「見つかりません」に変換するようなことは避けてください。サーバーまたは静的生成パスが実際の 404 を生成する必要があります。

事前レンダリングを行っても、ページが自動的に高速になったりインタラクティブになったりするわけではありません。クライアントコンポーネントが多すぎる SSR/SSG/ISR ページは、依然として JavaScript のダウンロード、パース、ハイドレーションのコストがかかります。適切に分割され、近くのデータを使用する CSR は、ログイン時のナビゲーションで良好なパフォーマンスを発揮します。TTFB、LCP、INP、ロングタスク、ダウンロードおよび実行された JavaScript、そして表示から操作可能になるまでの時間を測定してください。

データの重要度(リスク)に応じて障害時の挙動を分類します。

  • ガイドまたは商品本文の再生成失敗: 最後に成功したバージョンを配信し、更新時刻を公開し、古さにアラートを設定します。
  • 検索アップストリームのタイムアウト: 捏造された空の結果ではなく、再試行可能な障害または明示的に許可された短期キャッシュを表示します。
  • 価格または在庫 API の失敗: 古い値を確認済みとせず、チェックアウト前に再試行を要求します。
  • 注文 API の失敗: ロード済みの UI を保持して再試行を提示し、共有キャッシュを介してユーザー間でフォールバックすることは絶対に避けます。
  • 無効化イベントの遅延: エンティティのバージョンをリコンシリエーションし、正規データより遅れているページを見つけて、補償的な無効化を発行します。

ステップ 4: 本番ビルドとビジネスメトリクスで検証する

開発モードでは、静的生成と ISR の挙動を証明できません。4 つのルートファミリすべてを検証する前に、本番用にビルドし、本番サーバーを実行してください。少なくとも以下のテストを網羅します。

  1. ビルド出力を検査し、キャッシュされていない 1 回の読み取りによって意図せず SSR になってしまうのではなく、各ルートが意図したとおりに静的、オンデマンド、または動的になっていることを確認します。
  2. 1 つの商品を繰り返しリクエストしてキャッシュヒットを証明し、その後更新して、イベント、無効化、最初の新しい HTML が返るまでの時間を記録します。
  3. 再生成の依存関係を失敗させ、最後に成功した本文が維持されエラーが記録されることを証明した後、復旧させます。
  4. さまざまなロケール、地域、通貨、認証状態でリクエストを行い、完全なキーとプライベートレスポンスの分離を証明します。
  5. 初期 HTML を直接取得して本文、メタデータ、canonical、404 を検証し、その後実際のブラウザを使用してハイドレーションを検証します。
  6. 外部 CDN と複数インスタンスをモデル化し、無効化がすべてのレイヤーとインスタンスに到達することを証明します。
  7. 実際のページ分布を用いて、ビルド時間、オリジンレンダリング QPS、ヒット率、TTFB、LCP、INP、JS コストを測定します。
  8. 表示された値をチェックアウトの権威あるデータと比較し、最適化によってトランザクションの正確性が損なわれないよう、価格や在庫の競合を監視します。

ルートごとに移行します。現在の SSR トラフィックと正確性を観察し、リスクの低いガイドを静的配信に移行します。キャッシュが何を返すかを記録することで、まずシャドウモードで商品の ISR を実行します。無効化の信頼性が証明された後にのみ配信を開始します。正確性またはコンテンツ経過時間の制限をトリガーとして、以前の戦略へルートごとにロールバックできるように維持してください。

質の高い回答例

「アプリケーション全体に対して 1 つの略語を選択することはありません。ガイドは公開され、均一で、編集頻度が低いため、静的 HTML をビルドし、CMS の公開成功後にパスを無効化します。初期テキストはインデックス可能な状態を維持し、ほぼすべてのリクエストが静的キャッシュを使用します。100 万件の商品 URL があるため、アクセスの多い商品は事前ビルドし、残りは初回アクセス時に生成します。商品本文は ISR を使用し、商品 ID で無効化します。300 秒という時間は失われたイベントの補償としてのみ使用します。期限切れ後の最初のリクエストは古いコンテンツを受け取ってバックグラウンド生成を開始する可能性があるため、300 秒が厳密な最大値であると約束するのではなく、エンティティの更新時刻とキャッシュ生成時刻のギャップを監視します。」

「価格、在庫、配送の可否は、本文のステイルウィンドウを継承しません。ブラウザが権威あるソースからそれらを更新し、チェックアウト時にサーバー上で再計算して、価格が変更された場合は確認を求めます。検索は組み合わせが多すぎ、クエリごとに変化するため、初回表示は SSR とし、その後のフィルターはクライアントが担当します。認証やパーソナライズされた条件を含むレスポンスが共有キャッシュに入ることは決してありません。注文は認証済みシェルと CSR データを使用し、サーバーサイドでのユーザー認可と noindex を備えます。」

「本番ビルドで実際のルートモードを検証し、ヒット、イベント無効化、300 秒のフォールバック、再生成失敗、およびリカバリをテストします。外部 CDN は Next.js と同期してパージする必要があり、複数インスタンスには同期された無効化が必要です。初期の公開 HTML の本文、canonical、ステータスを検査し、実際のブラウザで TTFB、LCP、INP、JavaScript コストを測定します。最後に、表示価格とチェックアウト価格を比較します。トランザクションの正確性が低下しているのにパフォーマンス指標だけが合格している状態は、依然として失敗です。」

よくある間違いと改善策

  • アプリケーションに 1 つの戦略を選択する → 公開ページ、検索ページ、プライベートページで要件が異なる → ルートごと、場合によってはデータ領域ごとに決定する。
  • SSR を SEO の保証として扱う → メタデータ、ステータス、canonical、クロール可能なリンクが依然として間違っている可能性がある → 初期 HTML とクローラーの出力を検査する。
  • CSR は検索エンジンに完全に認識されないと主張する → Google は JavaScript をレンダリングできるが、キューイングが発生し、他のボットでは能力が異なる → 主要な公開コンテンツを事前レンダリングし、その制限を正確に説明する。
  • revalidate=300 を厳密な 5 分の SLA として扱う → 低トラフィック、バックグラウンド処理、障害によって古さが延長される → イベント無効化、経過時間監視、時間フォールバックを組み合わせる。
  • ページ全体に 1 つの鮮度ルールを適用する → 説明文は古さを許容するが、価格と在庫はそこから保証できない → リスクごとにデータを分割し、トランザクション境界で再確認する。
  • Next.js のみをパージする → 外部 CDN や別のインスタンスがコピーを保持している可能性がある → すべてのキャッシュをマッピングし、伝播をテストする。
  • 事前レンダリング=高速と決めつける → 過剰な JavaScript、ハイドレーション、遅いアップストリームは依然として悪影響を与える → ネットワーク、メインスレッド、Web Vitals、サーバーメトリクスを測定する。
  • 開発環境でのみ ISR をテストする → 開発環境の挙動は本番のキャッシュを代表しない → ヒット、無効化、障害テストには本番ビルドと本番サーバーを使用する。
  • あらゆるエラーを隠すために古いページを使用する → 空の検索、古い価格、ユーザー間の注文データの混混入は、誤った判断や情報漏洩を引き起こす → データのリスクに応じて stale-if-error を定義する。

フォローアップの質問

商品の変更を 10 秒以内にグローバルに反映する必要がある場合、ISR を維持できますか?

はい、ただし 10 秒をエンドツーエンドの無効化 SLO にする必要があります。カタログトランザクションがコミットされた後、バージョン管理されたイベントを確実に発行し、すべての Next.js インスタンス間でタグの無効化を同期し、外部 CDN をパージして、複数の地域から新しいバージョンをプローブします。時間による再検証は補償策であり、10 秒の保証ではありません。パージチェーンが目標を達成できない場合は、そのフィールドを動的に読み取るか、境界を証明できる短いキャッシュパスを使用します。

100 万件の商品を静的生成することが問題になるのはなぜですか?

多くのロングテールページは一度も読まれない可能性があるにもかかわらず、ビルド時間、生成物、リリースリスクがページ数と密結合してしまうためです。アクセスの多い商品を事前ビルドし、残りは初回リクエスト時に生成します。再生成の同時実行数を制限し、ホットイベントが再生成ストームを引き起こすのを防ぎ、存在しない商品に対する信頼性の高い 404 の挙動を維持します。

SSR レスポンスを CDN にキャッシュできますか?

共有可能かどうかは、SSR という名称ではなく、キャッシュキーのすべてのディメンションにわたってレスポンスが同一であるかどうかに依存します。完全なキーを持ち、短時間の古さが許可されている公開検索レスポンスは、慎重にキャッシュできます。Cookie、ユーザー権限、パーソナライズされた価格、テストグループへの所属に関わるレスポンスは、プライベートにするかキャッシュ不可にする必要があります。Vary、キーの構築、ログアウト後のユーザー間の分離をテストしてください。

RSC、ストリーミング SSR、PPR は 4 つの戦略モデルを無効にしますか?

これらにより、1 つのルート内で静的処理と動的処理をより細かく組み合わせることができるようになりますが、意思決定の入力情報がなくなるわけではありません。処理がどこで実行されるか、初期 HTML に何が含まれるか、データがどれくらいの期間キャッシュされるか、クライアントが受け取る JavaScript の量、動的領域がどのように失敗するかを明記する必要があります。面接では、CSR/SSR/SSG/ISR の配信と鮮度を確立した上で、RSC、ストリーミング、または部分事前レンダリング(PPR)が特定の領域をどのように改善するかを説明してください。

無効化ストーム(Invalidation Storm)をどのように防ぎますか?

エンティティごとに重複するイベントを集約し、古いバージョンを拒否し、制限された再生成の同時実行数とジッター(ゆらぎ)を追加し、キャッシュキーごとに 1 つのジェネレーターのみを許可します。キューの深さ、生成時間、失敗、コンテンツの経過時間を監視します。バックログが増加した場合、商品本文は最後に成功したバージョンを配信し続けながら、価格と在庫については権威ある動的読み取りを維持します。

公開情報ソース

関連する質問