🎉

レンダリング方式に纏わる分類の違いについて

に公開

はじめに

Next.js で良く出てくる概念として、

  • SSR / SSG / ISR / ISG / CSR
  • 静的 / 動的レンダリング
  • クライアント / サーバーコンポーネント

などがあります。
良くごっちゃになるので、役割・関係についてまとめました。

1. 動的レンダリング / 静的レンダリング

画面に表示されるページは最終的に HTML+JavaScript の形を取ります。この動的・静的のカテゴリは、その HTML を ”いつ生成するか” で分類したものです。

静的レンダリング (Static Rendering)

静的レンダリングは、ページの HTML を事前に生成・キャッシュしておき、各ユーザーへのリクエスト時にはその完成済みの結果をそのまま返す手法です。

  • 仕組み: ビルド時(デプロイ時)や定期的な再生成タイミングでサーバー側でレンダリングを行い、出来上がった HTML ファイルを配信します
  • メリット:
    • 表示が高速(サーバーは新たな計算をせず既に用意された HTML を返すだけ)
    • CDN を通じてグローバルにキャッシュ配信できる
    • サーバー側の処理負荷を大幅に削減
    • SEO に有利(ページロード時点で HTML が完成しているため検索エンジンが認識しやすい)
  • デメリット:
    • ビルド後に内容が変更されても即座には反映されない
    • 頻繁に更新されるデータには不向き
    • ユーザーごとにパーソナライズされた内容の表示には不向き
参考: ビルドとは何か

「ビルド」 とは、下記全フェーズ(型チェック → トランスパイル → バンドル → プリレンダリング → 最適化 → デプロイ成果物生成)のことです。

ビルドフロー概要

フェーズ 実行タイミング 主な処理 成果物
1. ソース解析・型チェック next build コマンド実行直後 - TypeScript の型チェック(tsc --noEmit 相当)
- ESLint/Biome などの静的解析(設定次第)
型エラー検出レポート
(エラーがあればビルド失敗)
2. トランスパイル ソース解析後 → 各モジュール単位で - .ts / .tsx を Babel + TypeScript プラグインで JavaScript に変換
- JSX → React.createElement 呼び出しに変換
中間 JS モジュール(ESM)
3. バンドル トランスパイル後 → クライアント/サーバー別 - クライアントバンドル:アプリで使う React/依存ライブラリを1つ以上のチャンクにまとめる
- サーバーバンドル:API Routes や SSR 関数などサーバー実行用にまとめる
/next/static/chunks/...
server/pages/…(サーバー関数のバンドル)
4. プリレンダリング バンドル完了後 - SSG(Static)対象ページgetStaticPropsgenerateStaticParams を呼び出し、HTML +関連 JSON を生成
- App Router ではサーバーコンポーネントを実行し静的 HTML を出力
out/_next/static/pages/... .html
out/_next/data/... .json(SSG 用データ)
5. アセット最適化 プリレンダリング後 - 画像・フォントの最適化
- ソースマップ生成
- ブラウザキャッシュ用ハッシュ付きファイル名付与
最終的な静的ファイル群
_next/static/... ディレクトリ
6. デプロイ用成果物生成 上記すべて完了後 - 静的ページ(SSG, ISR キャッシュ)
- サーバーレス関数(SSR や API Routes 用)
- クライアント側 JS/CSS チャンク集合
Vercel / Netlify / Node.js サーバー へアップロードするフォルダ構成

各ステップのポイント

  1. ソース解析・型チェック

    • next build が実行されるとまず TypeScript の型エラーをチェック。
    • 型エラーや ESLint エラーがあるとそこで止まり、以降のバンドルは行われません。
  2. トランスパイル

    • TypeScript → JavaScript(ESM)への変換。
    • JSX や最新の ES 機能もここで後ろ向き互換変換されるので、古いブラウザにも対応できるコードになります。
  3. バンドル

    • クライアントで使うコードと、サーバー(API Routes/SSR)で使うコードを分けて束ねます。
    • Next.js はデフォルトで Webpack(または Turbopack)を用いて、両方のバンドルを同時に生成します。
  4. プリレンダリング

    • SSG 対象のページはこの段階で HTML を完成させ、静的ファイルとして出力。
    • App Router のサーバーコンポーネントも同様に、ビルド時に実行すれば静的 HTML が生成されます(=静的レンダリング)。
  5. アセット最適化

    • 出力済みの画像やフォントを圧縮・リサイズしたり、CSS の不要部分を削ったり。
    • キャッシュバスティング用にファイル名にハッシュを付与します。
  6. デプロイ用成果物生成

    • これで「ビルド時に完成する」成果物がすべてそろい、サーバーまたは CDN にアップロード可能な状態になります。
    • 静的ファイルはそのまま配信、SSR/ISR 用のサーバーバンドルはサーバーレス関数として実行環境に配置されます。

動的レンダリング (Dynamic Rendering)

動的レンダリングは、各ユーザーからのリクエストごとにサーバー側でページ内容を生成する手法です。

  • 仕組み: ページ閲覧のたびに都度サーバーで必要なデータをフェッチして HTML をレンダリングし、結果をクライアントに送信します
  • メリット:
    • リアルタイムなコンテンツ変化に対応できる
    • ユーザーごとの個人設定を反映できる
    • リクエスト時点の最新情報を反映できる
    • ユーザー固有のコンテンツを提供できる
  • デメリット:
    • サーバー負荷が高くなる
    • 「常に最も遅いデータ取得にページ生成全体が左右される」(ボトルネックによって表示遅延が発生する可能性)

2. SSR / SSG / ISR / ISG / CSR

このカテゴリは、その HTML を ”いつ + どこで生成するか” で分類したものです。

SSR(Server Side Rendering: サーバーサイドレンダリング)

仕組み

SSR はユーザーからの各リクエストに対して、サーバー側で HTML コンテンツを動的に生成してからクライアントに送信する手法です。

  • ユーザーがページにアクセスするたび、その都度バックエンドでデータを取得
  • 取得したデータを埋め込んだ HTML をレンダリング
  • 出来上がった HTML をレスポンスとして返す

特徴とユースケース

SSR は初回ページロードの高速化SEOの面で大きな効果を発揮します。

適したケース:

  • SEO を重視するウェブサイト(ブログ、メディアサイト、EC サイトの商品詳細など)
  • ユーザーごとのパーソナライズが必要なページ
  • リアルタイム性が要求されるページ(ニュースフィード、在庫情報など)

メリット

  • 初期表示速度の向上: サーバーでレンダリング済みの HTML を返すため速やかにコンテンツを表示
  • SEO に強い: HTML コンテンツが最初から存在するため検索エンジンに認識されやすい
  • 柔軟なデータ活用: リクエストごとにサーバーでデータフェッチできるため、動的データを反映可能

デメリット

  • サーバー負荷とスケーラビリティ: 全てのリクエストに対しサーバー処理が発生し、アクセス集中時に負荷増大
  • レスポンス生成の遅延: リクエストを受けてから HTML を組み立てるまでの処理時間が発生
  • オフライン対応の困難: ページ表示のたびにサーバーとの通信が必要

SSG(Static Site Generation: 静的サイト生成)

仕組み

SSG はビルド時にあらかじめページの HTML を生成しておく手法です。Next.js では特に何も設定を加えないとこれになります。

  • アプリのデプロイやビルド時にデータを取得
  • 各ページの静的 HTML ファイルを作成
  • ユーザーからのリクエスト時には即座にそのファイルを返すだけ

特徴とユースケース

SSG は更新頻度が低いコンテンツを高速かつ効率的に配信するのに適しています。

適したケース:

  • 企業のコーポレートサイト
  • ブログ記事
  • ドキュメントサイト
  • 商品紹介ランディングページ

メリット

  • 極めて高速な配信: 事前生成済みの HTML ファイルを即座に返せる(CDN キャッシュとの相性も良い)
  • サーバー負荷の低さ: リアルタイムの計算処理を行わないためサーバー負荷が小さく、大量アクセスに強い
  • SEO とセキュリティ: HTML が直接提供され、動的コードを実行しないためセキュリティリスクも低減

デメリット

  • コンテンツ更新の手間: 内容を更新するには再ビルド・再デプロイが必要
  • 動的機能への不向き: ユーザー固有データや時刻依存データの扱いが困難
  • ビルド時間の増大: サイトのページ数が多いとビルドプロセスが長時間化

ISR(Incremental Static Regeneration: 増分的静的再生成)

仕組み

ISR は事前生成した静的ページを一定間隔で再生成(更新)できるようにした手法です。

  • 基本は SSG と同様にビルド時にページを生成
  • 定期的または要求に応じてページを再レンダリングしてキャッシュを更新

特徴とユースケース

「基本は静的生成で高速に配信しつつ、一定時間ごとに内容を最新化したい」というニーズに応えます。

適したケース:

  • 更新頻度の高いブログサイト
  • 商品在庫情報を含む EC サイト

メリット

  • 静的高速性と最新データの両立: 静的ファイルとして配信しつつ、自動再生成によって比較的新しい情報を反映
  • スケーラビリティ: 必要なページだけを順次再生成できるため、サーバー負荷を抑えつつ更新可能

デメリット

  • 若干の陳腐化許容: 再生成間隔を設ける以上、その間の更新は次の再生成までは反映されない
  • 実装と仕組みの複雑さ: ビルドとサーバー再レンダリングのハイブリッド挙動を理解し設定する必要がある

ISG(Incremental Static Generation: 増分的静的生成)

仕組み

ISG は大量の静的ページを持つサイトでビルド時に全ページを生成しないことでビルド時間の問題を解決する手法です。

  • 代表的なページだけビルド時に生成
  • その他のページは初めてリクエストが来た時に生成してキャッシュ
  • 以降のアクセスは静的ページとして提供

特徴とユースケース

ページ数が極めて多いサイトで有用です。

適したケース:

  • 数万の商品詳細ページを持つ EC サイト
  • 膨大な記事アーカイブを持つニュースサイト

メリット

  • ビルド時間の短縮: 全ページを一括ビルドしないため、サイト全体のビルド時間・コストを抑制
  • 静的配信の恩恵維持: 一度生成されたページは静的ファイルとしてキャッシュされ高速応答可能

デメリット

  • 初回アクセスの遅延: 未生成のページに最初にアクセスしたユーザーは待たされる
  • 実装の複雑さ: どのページを事前生成し、どのページを遅延生成にするか判断が必要

CSR(Client Side Rendering: クライアントサイドレンダリング)

仕組み

CSR はクライアントサイド(ブラウザ側)でページの描画やデータ操作を行うアプリケーション手法です。

  • 初回ページロード時に必要なリソース(HTML、CSS、JavaScript、画像など)を読み込み
  • 画面遷移やコンテンツ更新はクライアント上の JavaScript で実行
  • サーバーからはデータのみを取得(API 通信)

特徴とユースケース

ユーザービリティが高くリッチなインタラクションを提供できます。

適したケース:

  • 高度にインタラクティブなアプリケーション(メールクライアント、プロジェクト管理ツールなど)
  • ページ遷移を頻繁に行うソーシャルメディア/SNS

メリット

  • UX の向上: ページ全体のリロードが不要で画面遷移が高速・シームレス
  • クライアント側キャッシュ活用: 一度取得したデータを再利用でき、繰り返し閲覧が高速
  • 豊富なインタラクション: リッチな UI 表現、デスクトップアプリに匹敵する複雑な機能を実現可能

デメリット

  • 初期ロードが重い: アプリ全体のスクリプトやリソース読み込みに時間がかかる場合がある
  • SEO の弱さ: 初期 HTML にコンテンツが含まれない場合が多く、検索エンジン最適化に弱点
  • セキュリティ上の課題: コードの秘匿性が低く、XSS などのリスクにも注意が必要
CSR と SSG の違い
フェーズ CSR(クライアントレンダリング) SSG(静的サイト生成)
ビルド時の成果物 - JavaScript バンドルのみ
(必要なコードを1つの大きなファイルや分割されたファイル=チャンクにまとめる)
- 各ページの完成済み HTML ファイル
(中身入りのページをビルド時に生成)
- バンドル/チャンクも併せて生成
デプロイ後の配信 - サーバーは ほぼ空の HTML(=最低限のタグと <div id="__next"> などだけ)を返す
- クライアントにバンドル/チャンクを配信
- サーバーは 中身入りの HTML を返す
- 必要に応じて同じバンドル/チャンクを配信
初回表示の流れ 1. 空の HTML → 2. 大きめの JS をダウンロード → 3. JS 実行後に API からデータ取得 → 4. ブラウザ側でページを組み立て 1. 中身入り HTML を即表示 → 2. JS をダウンロード → 3. ハイドレーション(HTML に対して JS の動きを紐づけ)
その後のページ遷移 - 遷移ごとに API から JSON を取得 → クライアントで描画 - Next.js 特有で _next/data/...json を取得 → HTML を差し替えつつ表示(SPA 風にも動く)

まとめ

手法 レンダリング種別 レンダリングタイミング ページ単位実行環境
SSR 動的 リクエスト時 サーバー
SSG 静的 ビルド時 サーバー
ISR ハイブリッド(静的+再生成) ビルド時 → 指定間隔でバックグラウンド再生成(リクエスト時) サーバー
ISG ハイブリッド(オンデマンド静的) 初回アクセス時に動的生成 → 以降は静的キャッシュ サーバー
CSR (ランタイム生成という意味で、クライアント側で)動的 クライアント初回ロード後 クライアント

3. サーバーコンポーネントとクライアントコンポーネント

この サーバーコンポーネント(SC) / クライアントコンポーネント(CC) のカテゴリは、コンポーネント単位でレンダリングを ”どこで生成するか” で分類したものです。

サーバーコンポーネント (Server Components)

概要と特徴

サーバーコンポーネントはレンダリング処理をサーバー側で行い、その結果(HTML やシリアライズされたデータ)だけをクライアントに送ります。

  • ユーザーのリクエスト時にサーバー側で実行・描画
  • 完成した HTML がクライアントに送信される
  • ブラウザは受け取った HTML を静的コンテンツとして描画

App Router ではデフォルトでコンポーネントはサーバーコンポーネントとして扱われます。

主な利点

  1. 非インタラクティブな UI の効率的レンダリング

    • 静的コンテンツの表示に最適
    • ブログ記事、ドキュメント、ランディングページなどに向いている
  2. サーバーサイドでのデータ取得と機密情報の安全な扱い

    • データベース問い合わせや外部 API 呼び出しを直接実装可能
    • API キーやクレデンシャルをクライアント側に漏らさず安全に扱える
  3. クライアントへの JavaScript 送信不要(軽量なページロード)

    • 結果としての HTML だけをクライアントに送る
    • ブラウザに送る JavaScript バンドルサイズが小さくなる

制約

  • イベントハンドリングや状態管理が不可

    • onClickonSubmitなどのイベントハンドラを直接使用できない
    • useStateuseEffectなどの React フックが使用できない
  • インタラクティブな要素には不向き

    • ユーザー操作に応じて UI が変化する部分には使えない

クライアントコンポーネント (Client Components)

概要と特徴

クライアントコンポーネントはブラウザ上で動作するコンポーネントです。

  • サーバーでプリレンダリングした HTML が提供される
  • クライアント側の JavaScript がハイドレーション(再構築・インタラクティブ化)を行う
  • コンポーネントのファイル先頭に "use client" ディレクティブを記述して指定

主な特徴と用途

  1. ユーザーとのインタラクション実現

    • ユーザー操作に応答する UI を担当
    • イベントハンドラや React フックを使用可能
    • フォーム入力、カウンター、モーダルウィンドウなどに適した選択肢
  2. リッチなブラウザ API 活用

    • windowlocalStorageなどブラウザ環境の API を利用可能
    • Canvas、WebGL、位置情報など、ブラウザ特有の機能を活用できる

トレードオフ(デメリット)

  • 初期ロード時の負荷増大

    • JavaScript コードをダウンロード・解析・実行する必要がある
    • ハイドレーションによる遅延が発生し得る
  • 状態管理の複雑化

    • コンポーネント間で状態共有・同期が必要になると複雑度が増す
    • グローバルな状態管理の導入が必要になる場合がある
  • SEO や初期表示の課題

    • クライアントコンポーネントのみだと初期 HTML が空になりがち
    • サーバーコンポーネントとの組み合わせで解決することが多い

4. おまけ: SPA とは

CSR と間違えられている印象。
SPA: シングルページアプリケーションは、アプリレベルのレンダリング戦略の一つで、「ページ全体を再読み込みせずに、クライアント上で画面を切り替える」という発想です。空の HTML ファイルが単一ページで、その中で JavaScript を用いて画面を描画するというルーティングを取ります。
対称となるのは MPA: マルチページアプリケーションで、これは単純にアクセスされたページを都度表示するという戦略です。

項目 MPA SPA
技術構成 - サーバーサイドテンプレート(PHP, Django, Rails, JSP など)
- フルページ SSR(リクエストごとに HTML を再生成)
- 純粋な html+css+javascript で作るサイトなどもこれ
- クライアントフレームワーク(React, Vue, Angular など)
- CSR(HTML シェル+ JS バンドル)
初回リクエスト時 1. ブラウザ → サーバー:GET /page リクエスト
2. サーバー:テンプレート+ DB/API → 完成済み HTML を生成
3. サーバー → ブラウザ:HTML + CSS +必要な JS を返却
4. ブラウザ:HTML を描画し、ページ全体が表示
1. ブラウザ → サーバー:GET /(or /dashboard
2. サーバー:ほぼ空の HTML シェルを返却(<div id="app">など)
3. ブラウザ:シェル描画後、JS バンドルをダウンロード&実行
4. JS 実行中に API を呼び出してデータ取得 → クライアント側で DOM 構築
画面操作時 - リンククリックやフォーム送信で ページ全体を再読み込み
- 毎回サーバーへリクエスト、新しい HTML を取得してブラウザが再描画
- リンククリックは History API で URL を書き換え
- 画面遷移は フレームワーク内ルーター が差分だけ描画
- 全体のページリロードなしで表示切替
JS/データの動き - ページごとに必要な JS を HTML 内で読み込む
- インタラクティブ部分は各ページ読み込み時に都度初期化
- データはサーバーが埋め込んだ HTML で渡される(必要に応じ Ajax)
- 初回に一括ダウンロードしたバンドルを常駐
- 各画面で必要なデータは クライアント側で Ajax/fetch
- 以降は JS が常時動作し、API 呼び出しやキャッシュでデータ取得
UX/パフォーマンス - 初回含めリンク切り替えごとに「白紙 →HTML 取得 → 描画」のフラッシュが起こる
- SEO に強い(常に中身入り HTML)
- 初回ロードは重いが、遷移はスムーズで「ネイティブアプリ」感覚
- SEO 対策には SSR/SSG とのハイブリッドが必要な場合も
利点 - 実装がシンプル
- SEO&共有リンクで必ず正しい HTML が返る
- 初期表示後もサーバー返却 HTML を直接再利用
- 画面遷移が高速・シームレス
- クライアント側できめ細かい UX 制御が可能
- オフラインやプレフェッチが効きやすい
欠点 - 毎回フルリロードして画面がチラつく
- ユーザー操作ごとにサーバー負荷が発生
- 初回ロードが遅い
- SEO や共有リンクで追加対策が必要
- バンドルサイズが肥大化しやすい

まとめ

  1. 動的レンダリング / 静的レンダリング
    • どちらもサーバーサイドで html をレンダリングする
    • レンダリングするタイミングが違う
  2. SSR / SSG / ISR / ISG / CSR
    • どこで、いつレンダリングするかが違う
    • SSR, CSR は動的
    • それ以外はほぼ静的
    • CSR 以外はサーバー側でレンダリングする
  3. サーバーコンポーネントとクライアントコンポーネント
    • コンポーネント単位
    • レンダリングをする場所がサーバーかクライアントか
KA projects

Discussion