EN

CSR・SSR・SSGは「HTMLをいつ組み立てるか」の違い

この記事の内容は次のとおりです。

Webページの「作り方」は3種類ある

WebページのHTMLをいつ、どこで組み立てるかには3つのやり方があります。まず略称から。

略称正式名称日本語ひとことで言うと
CSRClient-Side Renderingクライアントサイドレンダリングブラウザが組み立てる
SSRServer-Side Renderingサーバーサイドレンダリングアクセスのたびにサーバーが組み立てる
SSGStatic Site Generation静的サイト生成公開前にあらかじめ組み立てておく

レストランで例えると

SSGは「作り置きのお弁当」です。開店前に作って並べてあるので、注文したらすぐ出てきます。ただし中身は全員同じで、開店後にメニューを変えることはできません。

SSG。公開前に1回だけコードとコンテンツからHTMLを組み立てて保存し、アクセスのたびにはその完成品をそのまま返す図 公開前(1回だけ) コード・コンテンツ ビルド 完成したHTML保存しておく 公開 アクセスのたびに(何度でも) ブラウザ サーバー GET / 保存済みのHTMLをそのまま返す(組み立てない)

SSRは「注文を受けてから作る料理」です。その人に合わせて中身を変えられますし、いつでも最新の食材が使えます。そのぶん、出てくるまでにキッチンが動く時間がかかります。

SSR。公開時点ではまだ何も組み立てておらず、アクセスのたびにサーバーがその場でデータを取得してHTMLを組み立てる図 公開前(1回だけ) まだ何も組み立てていない 公開 / 最初のアクセス アクセスのたびに(毎回ここから) ブラウザ サーバー GET /topics サーバーがここでHTMLを組み立てる(データ取得 → テンプレートに反映) 完成したHTML

CSRは「空の皿と、食材+レシピの入った袋を渡して、持ち帰って作ってもらう」やり方です。お店(サーバー)が渡すのは空の皿(空のHTML)と袋(JS)だけなので身軽ですが、持ち帰ってから自分で調理して皿に盛り付ける(ブラウザがJSを実行してHTMLを組み立てる)ぶん、食べられるまで一番時間がかかります。

CSR。サーバーは空のHTMLとJSファイルを返すだけで、ブラウザがJSを実行してデータを取得し、その場でHTMLを組み立てて初めてページが表示される図 公開前(1回だけ) コード(JSファイル)を配れる状態にしておくだけ 公開 / 最初のアクセス アクセスのたびに(毎回ここから) ブラウザ サーバー GET /rooms/xxx 空のHTML + JSファイル ブラウザがJSを実行し、APIを呼ぶ準備をする GET /api/messages データ(JSON) ここでブラウザがHTMLを組み立て、ようやくページが表示される

ここで、店(サーバー)の料理(HTML)の写真を撮りに来る人——クローラーさん——が登場します。クローラーとは、検索エンジンやSNSがWebページを自動で巡回させているプログラムのことです。ページの中身を読み取って、検索結果やリンクのプレビューに使います。

クローラーさんは食べに来たわけではなく、写真を撮りに来ただけです。そしてクローラーは、その場で調理が終わるのを待ってはくれません。だからCSRでは、渡された時点の皿——まだ何も盛り付けられていない皿——しか写真に撮れません。

皿の中身が読み取れなければ、Google検索やYahoo検索の検索結果には出てきません。一般に、クローラーがページの中身をすぐ認識できるほど、検索結果の上位にも組み込まれやすいとされています。

クローラーさんが同じサーバーを巡回しても、見つけるものは方式によって変わります。

クローラーさんがサーバーを巡回したとき、SSR・SSGでは完成した料理が乗った皿を見つけられるが、CSRでは空の皿しか見つけられない図 SSR・SSGの場合クローラーさんサーバー皿完成した料理が乗っている中身を読み取れる→ 検索結果に反映されうる CSRの場合クローラーさんサーバー皿空っぽ(空のHTML)中身が見えない→ 検索結果に反映されない

選び方は、たった1つの質問で決まる

そのページの中身は、全員に同じで、公開前に決まっているか?

  • はい → SSG(作り置きできる)
  • いいえ → SSR(その場で作るしかない)

「ログイン中のユーザー名が出る」「在庫数がリアルタイムで変わる」といったページは、そもそも作り置きできないのでSSRになります。逆に会社紹介やブログ記事のように、誰が見ても同じで、更新のたびに作り直せば済むものはSSGが向いています。

SSRとCSR、どちらも「作り置きできない」なら何で決めるか

この質問1つで決まるのはSSGとそれ以外の境目までです。「いいえ」に転んだ先のSSRとCSRは、実は似た者どうしで、ここの使い分けのほうが迷います。両方とも「その場で組み立てる」点は同じで、組み立てる場所がサーバーかブラウザかだけが違います。

判断材料は主に2つです。

  1. 検索エンジンに見せたいか。 SSRは完成品のHTMLをそのまま返すので、クローラーにもすぐ読めます。CSRは空の皿を返すだけなので、前述のとおりクローラーには中身が見えません。検索結果に出したいページはSSRです。
  2. 開いたあとも中身が動き続けるか。 チャットやダッシュボードのように、開いたあともサーバーとやり取りしながら中身が変わり続ける画面では、最初のHTMLをサーバーが律儀に組み立てても、表示した瞬間から古くなっていきます。だったら最初からブラウザ側で完結させ、以降の更新もブラウザ主導にしてしまうほうが理にかなっています。これがCSRです。

つまり、検索に出したくて、開いたあとは中身が変わらない画面はSSR、検索に出す必要がなく、開いたあともずっと動き続ける画面はCSR、という組み合わせが典型です。両方の条件が一致しない画面(検索には出したいが動き続ける、など)は、素直には決まらず悩みどころとして残ります。

全員に同じで公開前に決まっているかでまずSSGを切り分け、残りを検索エンジンに見せたいか・開いたあとも中身が動き続けるかの2軸でSSR・CSRに振り分ける条件分岐図。どちらの軸も一致しない組み合わせは1つの悩みどころに合流する 全員に同じで、公開前に決まっている? SSG はい 検索エンジンに見せたい? いいえ 開いたあとも動き続ける? はい 開いたあとも動き続ける? いいえ SSR典型のパターン いいえ CSR典型のパターン はい 悩みどころSSRかCSRか、要検討 はい いいえ

実際のプロジェクトでの使い分け

個人開発で作っている匿名チャットサービスの、画面ごとの選択です。

画面パス選択理由
トップページ/SSG中身がコードの中にあり、誰が見ても同じ。検索と広告の入口なので、最速で返したい
サービス紹介/aboutSSG同上
トピック選択/topicsSSR話題の一覧は管理画面から変えられる。作り置きすると、古い一覧を配り続けてしまう
マッチング待機/waitingSSR待機状況は人によって違う。そもそも作り置きができない
チャットルーム/rooms/{id}CSRリアルタイムに会話が流れる画面。検索結果に出す必要もない

この表から読み取れること

1つのサイトの中で、3つすべてを使い分けています。 「このサイトはSSRで作りました」という言い方をすることがありますが、実際には画面ごとに向き不向きがあり、混ぜて使うのが普通です。

検索に出したい画面ほど、作り置き(SSG)に寄せています。 速く返せるうえ、クローラーが来た時点で中身が完成しているからです。

逆に、検索に出す必要のない画面では、SSRを選ぶ積極的な理由が1つ消えます。 チャットルームは会員だけが見る画面なので、検索エンジンに読ませる意味がありません。とはいえ「検索に出さなくていい」だけならSSRのままでも困らない話で、これだけではCSRを選ぶ理由になりません。チャットルームがCSRになった決め手は前節の2つめの軸——開いたあとも中身が動き続けるか——のほうです。会話はWebSocketで流れ続けるので、最初のHTMLをサーバーが丁寧に組み立てても、表示した瞬間から古くなります。「CSRはSEOに悪い」と一括りにするのではなく、検索に出したいか、開いたあとも動き続けるかの両方で決めるのが実際のところです。