SSR (Server-Side Rendering)

リクエストのたびにサーバーで HTML を生成して返すレンダリング戦略。ブラウザは受け取った瞬間から表示できるため初回表示が速く、SEO・OGP に完全対応する。代償はリクエストごとのサーバー計算コストと運用。レンダリング戦略の一角。

二つの世代

古典 SSRモダン SSR
代表CGI, PHP, Rails, DjangoNext.js, Nuxt, SvelteKit
クライアント側HTML は完成品。動きは jQuery 等を別途追加同じコンポーネントをクライアントでも実行して hydration
遷移フルページリロード(MPA)2 ページ目以降は SPA 遷移
コードベースサーバー用とクライアント用が分離isomorphic / universal — 1 つのコードが両方で動く

モダン SSR の核心は isomorphic JavaScript: React の renderToString 等で、同じコンポーネントツリーをサーバーでは HTML 文字列に、クライアントでは DOM 操作に使う。「Rails への回帰」ではなく、CSR の資産(コンポーネントモデル)を保ったまま初回だけサーバーで描く折衷。

Hydration — SSR を理解する鍵

サーバー産の HTML は見えるが操作できない(イベントハンドラが無い)。クライアントで同じコンポーネントツリーを再構築し、既存の DOM に紐付けてハンドラを張る処理が hydration。

sequenceDiagram
    participant B as ブラウザ
    participant S as サーバー
    B->>S: GET /products/42
    Note over S: データ取得 + renderToString
    S-->>B: 完成した HTML
    Note over B: 即表示できる (FCP) — でもまだ操作不能
    B->>S: GET bundle.js
    S-->>B: JS バンドル
    Note over B: hydration 完了 → 操作可能 (TTI)

ここから FCP と TTI のギャップ(見えるのに反応しない uncanny valley)が生まれる。しかも hydration はレンダリングとほぼ同等の計算を二度やる無駄を含むため、これを削る方向にフレームワークは進化している:

トレードオフ

長所短所
初回表示が速い(完成 HTML が届く)リクエストごとにサーバーで計算(コスト・スケール設計が必要)
SEO / OGP に完全対応TTFB がサーバー処理時間に依存
データ取得がサーバー内で完結(クライアントからの API 往復より速い)hydration のコストと FCP/TTI ギャップ
リクエスト時情報(Cookie・地域・A/B)でパーソナライズできるサーバー運用が必須(SSG のような「置くだけ」は不可)

向くケース

内容がユーザーやタイミングで変わり、かつ検索流入が重要なページ。EC の商品ページ、ニュース、SNS のフィード・プロフィール。内容が全員同じなら SSG で足り、SEO が不要なら CSR で足りる — SSR は両方の要件が重なったときの答え。

押さえどころ(カード化候補)

関連

Graph