はじめに
この記事では現代のフロントエンド開発のトレンドである(?)SPA(Single Page Application)とその構築に利用されるレンダリング技術に関して、色々調べて&実際に僕より遥かにベテランの方に教えてもらって情報をたくさんインプットしたのでまとめます。
まず、なぜこの記事を書こうと思ったのかというとこれまでタイトルの技術領域に関して以下のような解釈をしていました。
Twitterでフォロワーさんがピックアップしていたこちらの記事を読んで「あれ、僕の認識と結構違うぞ?」となって色々調べました。

調べてスライドにまとめて、2021/11/27(土)に開催した僕が運営する「つながる勉強会」でこの本記事と同じテーマについて登壇しました。

こちらが修正したスライドです↓
結論、僕が当初持っていた解釈である「SPA(シングルページアプリケーション)という大きな括りの中でCSR/SSR/SSGというレンダリング技術が存在する」というのは大体は間違っておらず、足りないところがいくつかあるという感じでした。
上記スライドでは載せきれない情報があるのと、せっかく色々教えてもらったのでちゃんと残しておこうと思います。
前提
なお、この記事で使用している図は先ほど掲載したスライドの一部です。
SPA(Single Page Application)について
SPAとは先述していますがSingle Page Application(シングルページアプリケーション)の略。
シングルページアプリケーションとは、Webアプリケーションの構成法の一つで、Webブラウザ側でページの移動を行わず、最初に読み込んだWebページ上のスクリプトがサーバとの通信や画面遷移を行う方式。
https://e-words.jp/w/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.html

上にも書いていますが、SPAはアプリケーションを構成するページが1枚しかなく、その1枚のページ上でJavaScriptを使ってページの中身を切り替えることによりページ遷移のような動きを表現します。
文字通り、1つのページで構築されたアプリケーションです。
では、SPAに使用されるレンダリング技術についてまとめます。
CSR(Client Side Rendering)について
CSRとは
Client Side Rendering(クライアントサイドレンダリング)の略。
文字通り、クライアントサイド(ブラウザ)で行うレンダリングのことです。
JS+ReactやVue.jsで開発したアプリケーションは基本的にCSRを行います。(SSRをするためのライブラリは使っていない前提なので「基本」と書いています)
CSRの仕組み
CSRの仕組みを図で表します。

CSRを使ったSPAの場合は、初回アクセスでアプリケーションの構築に必要なリソースを全てクライアントサイドで受け取ります。(リソースに関しては上図では簡易的に表すためHTML/CSS/JSコードを書いていますが、その他にも画像、PDF等がある可能性もあります)
受け取ったリソースを用いてクライアントサイド(ブラウザ)でページをレンダリングを行います。
レンダリングしてくれるのは読み込んだ JavaScriptコードです。
ページをレンダリングする上でDBに格納されたデータの取得をバックエンドのAPIに依頼する場合はクライアントからバックエンドのWeb サーバーにリクエストを送ることでJSONデータを取得します。
上記のリクエストの流れは例えばReactであればuseEffect
やAxios
を使うことで実現できます。

仕組みのまとめとして例えばですが、「CSRだけを使ってDBに登録した投稿データを一覧表示する画面を表示する」ケースは以下の順序です。
- クライアントからWebサーバーにGETリクエストを送る
- フロントエンド用Webサーバーはアプリケーションを構築する全てのリソースをクライアントに返却する
- クライアントでは受けとったリソースを使って一覧画面をレンダリング・描画する(この時点ではDBに登録されているデータは描画されていない)
- DBに登録されている投稿データを取得するためにクライアントからバックエンド用WebサーバーにGETリクエストを送る
- バックエンド用Webサーバー上で動くAPIで取得したJSONデータをクライアント返却する
- クライアントで受けとったJSONデータとJavaScriptを使って投稿データ一覧表示画面をレンダリング・描画する(完成)
CSRのメリット・デメリット
メリット
- 画面遷移の度にWebサーバーにHTMLを要求する必要がなく、クライアント(ブラウザ)で行うため画面遷移が高速(ブラウザのリロードマークもくるくるならない)
- SSR、SSG(SG)と比較して実装が楽
デメリット
- Webサーバーへの初回リクエストでアプリケーションに必要なリソースを全てを受け取る必要あるため、レンダリングするので初期表示が遅い
- ページ単位にOGPが設定することができない(1つのページのアプリケーションなのでそりゃそうか)
- SEO的に微妙?(※元々SPAは後述するSSR、SSGよりSEO的に不利だったので最近はそこまでは大差ないようです。この辺は結局どうなのかがよくわかっていません)
SSR(Server Side Rendering)について
JavaScriptでCSRだけで実装したSPAを開発する時のデメリットをカバーできるのがSSRです。
登場の順序的に「CSR→SSR」みたいな流れで紹介する記事がありますが、登場の順序としてはSSRはとても前から存在する技術です。
例えばLaravelでアプリケーションを開発するとWebサーバーでレンダリングしたHTMLをクライアントに返すのでこれも立派なSSRだと思います。
という前提を置きつつ、JavaScriptでのお話をしていきます。
SSRとは
Server Side Rendering(サーバーサイドレンダリング)の略。
これもCSR同様文字通りですが、サーバーサイドで行うレンダリングのことです。これはアクセスのたびに行われます。
SSRはNext.js、Nuxt.js等のフレームワークを使うことで比較的手軽に実装することができます。
(Next.jsは初めはSSR用のReactフレームワークとして登場したそうな)
SSRの仕組み
SSRの仕組みを図で表します。

SSRはサーバーサイドでレンダリングですから、クライアントからのリクエストを受けとったWebサーバー(フロントエンド用)でページをレンダリングします。
レンダリングする時にDBに登録されているデータを取得する必要がある場合にはDBにアクセスできるアプリケーションが存在するWebサーバーにフロントエンド用のWebサーバーからリクエストを送り、データを受けとります。
上図ではデータのやり取りはJSONとしていますが、必ずJSONである必要はありません。
これもCSRと同様のケースですが「SSRだけを使ってDBに登録した投稿データを一覧表示する画面を表示する」時の手順は以下のようになります。
- クライアントからフロントエンド用WebサーバーにGETリクエストを送る
- フロントエンド用WebサーバーはDBに登録されている投稿データを取得するためにバックエンド用WebサーバーにGETリクエストを送る
- バックエンド用Webサーバーはフロントエンド用Webサーバーに投稿データを返却する
- フロントエンド用Webサーバーで受けとった投稿データとHTML/CSS/JS等のリソースを使用してページをレンダリングする(Node.js環境)
- DBに登録されている投稿データを取得するためにクライアントからバックエンド用WebサーバーにGETリクエストを送る
- フロントエンド用Webサーバーはレンダリング結果をクライアントに返却する
- クライアントで受けとったHTMLを描画する
WebサーバーはデフォルトだとJavaScriptを実行できないので、JavaScriptを使用してSSRするためにはサーバーサイドでJavaScriptを実行するためにNode.jsが必要です。
SSRはページレンダリング技術であり、SSRされたページのUIを動的に変更するためにはクライアントでレンダリングを行います。
CSRだけで実装したSPAと同規模のアプリケーションにSSRを使用する場合、複数ページをSSRするSPAではなくMPA(マルチページアプリケーション)となります。
では「SSRだと必ずMPAになるのか?」と言えばそれはYESとは言い切れないかと思います。
例えば以下の場合(僕自身が実際に構築できる自信とか置いておきます)はSSRを使用しているけど、SPAです。
- クライアントでSSRしたHTMLを受けとってCSRする
- 1つのページのみSSRして以降の画面遷移やサーバーとの通信はクライアントで行う
上記はCSR+SSRで構築されたSPAとなります。
なので僕の今の認識では
です。
SSRのメリット・デメリット
メリット
- 初めのリクエストで全てのリソースを読み込む必要がないため、CSRより画面表示が早い
- 複数ページのアプリケーションを構築できるので、ページ単位でOGPの設定・SEO対策が可
デメリット
- Webサーバーでレンダリングする環境が必要であり、JavaScriptを使用する場合はNode.jsを準備する必要がある
- 上記の理由によりSPAと比べると実装が複雑で難易度高
SSG(Static Site Generator)について
SSRで発生してしまうサーバー絡みのアレコレをなくしたのがSSG。
SSGとは
SSGはStatic Site Generatorの略です。(日本語では「静的サイトジェネレーター」と呼ぶ)

仕組みはこれから書きますが、SSGの思想としては
アプリケーションをデプロイする段階とかでデータ取得もしておいて、ビルドして取得データも込み込みのページを作成してWebサーバーに配置しておけば良いじゃん
という感じです。
Next.jsではNext.jsで開発するアプリケーションはなるべくSSG(SG)を使うことを推奨しており、デフォルト設定のまま例えばVercel(Next.jsの開発元が提供するホスティングサービス)にデプロイしたタイミングでビルドを行い、SSGを行ってくれます。

SSGはNext.js、Nuxt.jsを使うことで実装することができます。
キャッチアップができないので確かですが、最近登場したフロントエンド開発での新しいフレームワークであるRemixはSSGできなかったような…
SSGの仕組み
SSGの仕組みを図示します。

他のレンダリング技術と同じく「SSGを使ってDBに登録した投稿データを一覧表示する画面を表示する」時の手順は以下のようになります。
- アプリケーション側で事前にビルドした時にバックエンド用Webサーバーから投稿データを取得した上でページをレンダリングしておき、フロントエンド用Webサーバーに配置しておく。
- クライアントからフロントエンド用WebサーバーにGETリクエストを送る
- フロントエンド用Webサーバーはレンダリング済みのHTMLをクライアントに返却する
- クライアントで受けとったHTMLを描画する
SSGはフロントエンド用Webサーバーでレンダリングしないので、Node.js(サーバーサイドでのJS実行環境)が不要です。
SSGで生成された静的なページをクライアントで表示させた後にUIを動的に変更する際にはCSRを行います。
SSGを複数ページに適用したアプリケーションはMPAになりますが、SSR同様「SSGだと必ずMPAになるのか?」の答えはNOだと思います。
例えば以下の場合はSSGを使用したSPAです。(実装したことない)
- SSGで生成されたHTMLをクライアントで受けとり、さらにそこからCSRして描画する
- 1つのページのみSSGで生成し、以降の画面遷移やサーバーとの通信はクライアントで行う
上記はCSR+SSGで構築されたSPAとなります。
なので僕の今の認識では
です。
フロントエンド開発でのレンダリング技術をまとめている技術記事の多くは(この記事もそうですが)CSR→SSR→SSGの順で説明しており、そうするとSSGが最も優れているかと思ってしまいそうですが必ずしもそうではないと考えます。
後述しますが、例えばDBに保存しているデータを一覧表示するページをSSGで生成した場合、DBのデータの変更(追加・更新・削除)をUIに反映するためにはその都度ビルドが必要となります。
なのでTwitterのようにユーザーが頻繁にコンテンツを増やしたり消したりして画面の表示が頻繁に変わるようなアプリケーションには適さず、ブログのような管理者がコンテンツを増減したい時に増減するようなアプリケーションに適してるといったようにアプリケーションの性質から考えて適するレンダリング方法が異なります。
SSGのメリット・デメリット
メリット
- ページのレンダリングを事前に済ませておくのでページの表示がSPA、SSRより高速
- サーバーサイドでのレンダリング実行環境(Node.js)が不要
- ページ単位でOGPの設定が可能
- SEO対策が可能
デメリット
- ページ数が多いアプリケーションではビルド時間が長くなる
- 画面に表示するコンテンツが頻繁に変更される場合、その変更の反映にはビルドが必要になる(Twitterのように多くのユーザーがコンテンツを登録したり削除したりするものは適さない)
SPA=CSRなのか?
この記事の最後に紹介しているSPA、CSR、SSR、SSG周りの記事では「SPA=CSR」と書かれているものが結構ありますが、これは正確には間違いです。(同義語ではないという意味)
まず、SPAは「アプリケーション」であり、CSRは「技術・仕組み」なので言葉のレベル的にイコールにはなりません。
SPAを構築するためにCSRは必須です。
必須ですが、CSRに加えてSSR、SSGを使ってSPAを構築することも可能なのでそういう意味もふまえてイコールではないと考えます。
ということで、よく技術記事は
- SPA(=CSR)
- SSR
- SSG
が同じレベルでまとめられていますが、これも正しくはないと考えます。(部分的に合っているところもあるので「間違っている」とは言えない)
色々な記事を読み、周りのエンジニアに教えてもらい、実際にこの記事を書いた上でSPAとCSR/SSR/SSGの関係というか立ち位置なのかについて僕なりに出した総括的な考えをまとめようと思います。
まとめ
まずはそれぞれの方式の特徴を表にまとめます。
レンダリング技術 | レンダリング | Node.jsが必要 | SPA構築に必須 | MPA構築が可能 |
---|---|---|---|---|
CSR | クライアント | – | ◯ | – |
SSR | サーバーサイド | ◯ | – | ◯ |
SSG | ビルド時 | – | – | ◯ |
その他の特徴なり所感はこちら。
- SPA(=CSR)/SSR/SSGという仲間分けではなく、SPAを構築するレンダリング技術としてCSR/SSR/SSGは存在する
- SPAを構築するのにCSRは必須、SSR、SSGは必須ではない
- JavaSvriptでマルチページアプリケーション(MPA)を構築する場合はSSRもしくはSSGを使うことで可能である
- SSRもSSGもそのページの初期レンダリングの方法であり、それ以降の差分のレンダリングは全てCSR
- SPA、SSR、SSGそれぞれにメリット・デメリットがあるので一概にどれが優れているわけではなく、開発したいアプリケーションの特徴によって上手に選定するのが大事
- と書きつつ、現状はなるべくにSSGを使うのが推奨されている流れ(と思います)
最後に
こうやってガッツリ記事を書いてみるといかに自分がフワッとした理解してしていなかったのかといかに勘違いしていたのかがわかりました(笑)
ただ、記事を書いてかなり理解度が深まったので時間をかけて記事を執筆した甲斐があったなと思います。(これまでのブログ記事の中で1番時間を要したかもしれませんw)
CSR、SSR、SSGの仕組みとかメリデメは個人的にはかなり理解が深まったのですが、HTMLレンダリングの細かいところとかやビルドとかまだ理解が浅いところがあるのでまた調べてブログにまとめたいです。
参考記事
大変勉強になる記事ばかりでした。感謝です。



コメント