レンダリング手法(SPA/SSR/SSG) - JavaScript
最終更新日: 2026-07-24
TOP(About this memo)) > 一覧(JavaScript) > レンダリング手法(SPA/SSR/SSG)
レンダリング手法の変遷(IMO)
- (IMO) Webのレンダリング手法は大まかに以下のように変遷してきたと理解している。
- サーバーからhtml/css/jsをダウンロードして表示する。
- サーバー側でPerlやPHP等が処理して加工したHTMLを返すようになる。
- JavaScriptで高度な処理をするようになる。
- フロント(html/js)とサーバー側(API)を分けるようになる(SPA)。
- サーバーとフロントが疎結合になる。
- フロントからデータをフェッチする際、何段階もフェッチすると待ち時間が発生しやすく、通信回数も多くなりやすい。
- フロント側の初回ダウンロードに時間がかかりやすい。多くのモジュールをバンドルしたJSファイルは比較的大きくなる。
- サーバー側で初期レンダリングや一部処理を分担するようになる(SSR)。
- フロントが処理に応じてオンデマンドでコンポーネントをダウンロードし、サーバーとクライアントでコンポーネントをシェアする方式も登場している(React Server Components等)。
- (?) 執筆時点では、React Server ComponentsはNext.jsのApp Routerを中心にすでに安定した機能として利用されている段階まで進んでいるとされる。詳細は後述の「近年の動向」を参照。
- (?) Angularは異なるアプローチを取っている可能性がある。
SPA/CSR(Client Side Rendering)
- ブラウザ上でJavaScriptを実行してDOMを生成・マウントし、コンテンツを表示する。
- 2回目以降の通信では、クライアントのJSでHTTPリクエスト(差分)を送り、JSONなどをサーバーから受け取り、クライアント側でHTMLを生成する。
- JSとHTMLをアップロードするだけで動くため、どこでもホスティングしやすい。
- 初期表示が遅くなりやすい。
- SEOで不利になりやすい。
- クローラーがJavaScriptを実行できるようになってきており、この問題は解決されつつある。ただし即時的に評価されるのではなく、評価までにラグがあるとされる。
- TwitterやFacebookのクローラーはJavaScriptを実行しないため、プレーンなSPAアプリだと動的なOGP対応ができない。
SSR(サーバーサイドレンダリング)
- SSRが必要となった背景
- SPAによってバックエンドAPIとフロントエンドの描画を完全に分離することで、開発体制の分離による生産性向上や、優れたUXの提供が可能になった。
- その一方で、過度なネットワーク通信が発生したり、JavaScriptによって生成されたWebサイトを検索エンジンのクローラーが検知しにくくなったりする問題があった。
- 遅いデバイスを使用していると、最初のページのレンダリングに時間がかかり、UXが低下する。
- 検索結果の上位に表示されにくいといったデメリットもあった(検索エンジン側の対応は進んできている)。
- これらの問題を解消するための手法がサーバーサイドレンダリング(SSR)。
- フロントエンドで行っていたレンダリングを、バックエンドのNode.jsサーバーと分担する考え方がSSR。
- 例えば、初期ページの一部だけをサーバーサイドでレンダリングし、残りの要素はフロントエンドからフェッチしてレンダリングする、というように用途に応じて使い分ける。
- モバイル端末の性能に依存せず、ハイパフォーマンスなサーバーでレンダリングできる。
- 無駄なネットワーク通信回数も最小限に減らせる。
- Node.jsが動くサーバーが必要。
- SSRを考慮した実装が必要。
- クローラーがレンダリング済みのHTMLを読み込めるため、SEO的に有利になりやすい(各ページのOGPやメタ情報をクローラーに渡しやすい)。
- GoogleはJavaScriptを実行してページごとのメタ情報を読み取っているとされるが、TwitterやFacebookのクローラーはそこまで対応していないとされる。
SSG(Static Site Generator)
- プリレンダリングとほぼ同義(例: Hugo等の静的サイトジェネレータ)。
- アプリのビルド時にあらかじめページ表示に必要なデータを取得し、各ページごとに静的なHTMLファイルを出力しておく。サーバーへのリクエスト時にはこのHTMLファイルを返却する。
- 例えばヘルプページのように、ユーザーごとに表示するコンテンツが変わらないページであれば、最初から静的なファイルとして用意しておく、という発想。
- HTMLファイルをアップロードするだけで動くため、どこでもホスティングしやすい。
- ページ表示までに必要な時間はCSR・SSRより高速になりやすい。
- SEOで不利になりにくい。
- 動的なOGP対応が可能。
- 上記の性質上、動的なデータが頻繁に変更される場合は採用しにくい。
JAMstack
- (参考) https://dyno.design/articles/what-is-JAMstack/
- サイトの各ページに相当するHTMLファイルをプログラムで事前に生成しておく。
- ブラウザからアクセスがあったときは、事前に生成したHTMLファイルの中身をそのまま返す。
- 動的な機能が必要な場合はJavaScriptとAPIを利用して実現する。
- CMSとの違い: JAMstackでは事前にページを生成する。
- SSGとの違い: JAMstackは動的な機能も含む。
- (?) SSGという用語自体が、JavaScript等でAPI取得するものも含む場合がある。
近年の動向(IMO・執筆時点の情報)
React Server Components (RSC) の普及
- React 18以降で導入されたコンポーネントの新しい区分。サーバー側でのみ実行され、クライアントにJSを送らない「サーバーコンポーネント」と、従来通りクライアント側でも動く「クライアントコンポーネント」を組み合わせて使う。
- Next.jsのApp Router(Next.js 13以降)がRSCを前提としたデフォルトの構成として採用しており、執筆時点ではNext.jsを使う場合の標準的な選択肢になっているとされる。
- データ取得をコンポーネント内で直接
async/awaitで行える「Server Actions」(フォーム送信などの更新処理をサーバー側の関数として直接呼び出せる仕組み)も組み合わせて使われることが多い。
- (?) 実装が複雑になりやすく、キャッシュの挙動が分かりにくいといった声もある。比較的新しい技術のため、セキュリティ面を含め今後も変化していく可能性がある領域だと考えられる。
メタフレームワークの再編
- RemixとReact Routerは2024年のReact Confで統合が発表され、Remixの機能はReact Router v7(2024年12月リリース)に統合された。執筆時点では新規プロジェクトはReact Router(v7以降)を使うことが推奨されているとされる。
- Next.js(React)、SvelteKit(Svelte)、Nuxt(Vue)、SolidStart(Solid)など、各UIライブラリに対応する形で「メタフレームワーク」(ルーティング・データ取得・SSR/SSG等をまとめて提供するフレームワーク)を使う構成が主流になっている。
Islands Architecture(アイランドアーキテクチャ)
- Astroなどが採用している考え方で、ページの大部分は静的なHTMLとして送り、インタラクティブな操作が必要な部分(「島」)だけを個別にハイドレーション(JSを紐付けて操作可能にする)する。
- SPA/SSR/SSGという分類とは別軸のアプローチで、クライアントに送るJSの量を大幅に減らせる点が特徴とされる。
Resumability(Qwikのアプローチ)
- Qwikが採用している考え方で、通常のSSR/ハイドレーションのように「サーバーでHTMLを作り、その後クライアントで全体を再実行してイベントを紐付け直す」のではなく、サーバー側での実行状態をシリアライズしてクライアントへ渡すことで、必要な部分だけを必要なタイミングで「再開(resume)」する。
- (?) ハイドレーション自体を極力避けることで初期表示の体感速度を高めることを狙ったアプローチとされる。
エッジでのレンダリング
- SSRの実行場所を、単一のオリジンサーバーではなく、CDNに近い「エッジ」(Vercel Edge Functions、Cloudflare Workers等)で行う構成が増えてきている。
- ユーザーに地理的に近い場所でレンダリングすることで、レイテンシを低減することを狙っている。
参考
SEOやキャッシュに関する参考