---
title: Jamstackのアーキテクチャパターン
description: Jamstackでは、「SPA」「SSG」「SSR」「ISR」の4つにアーキテクチャを分けることができます。それぞれの違いについて解説します。
---

Jamstackでは、そのHTMLレンダリング方式によって、アーキテクチャを4つに分けることができます。

- SPA
- SSG
- SSR
- ISR

ここでは、それぞれの違いについて解説します。

## それぞれの比較

各アーキテクチャにおける相違点を以下にまとめて紹介します。

|                 | SPA | SSG | SSR | ISR |
|-----------------|-----|-----|-----|-----|
| レンダリングを実行する場所 | クライアント | サーバー | サーバー | サーバー |
| ページレンダリングタイミング | クライアントがレスポンスを受け取った際 | サーバーがリクエストを受ける前に事前にページを生成 | サーバーがリクエストを受け取った際 | サーバーがリクエストを受け取った際(キャッシュが無い場合) |
| ページ内容の新しさ | ◎ | △ | ◎ | ○ |
| SEO              | △ | ◎ | ◎ | ◎ |
| 表示の高速さ      | ○ | ◎ | △ | ◎<br />(初回リクエスト時に生成) |
| 各ページのOGP     | × | ◎ | ◎ | ◎ |
| セキュリティ      | △ | ◎ | △ | ○ |
| サーバー負荷        | ○ | ◎ | △ | ○ |

## SPA

SPAはSingle Page Applicationの略になります。CSR（Client Side Rendering）とも呼ばれます。CSRの名前の通り、クライアント側でHTMLをレンダリングするのが特徴になります。SPAの場合、最初のリクエスト時にHTMLを返却します。続いてHTML内に記述されているJavaScript/CSSをリクエストおよび返却します。HTMLの返却方法としては静的または動的のいずれもありますが、多くの場合静的にHTMLを返します。

そして、さらに表示するのに必要なデータもAPI経由で取得するケースが多いです。最初に取得したHTMLをレンダリングした後、APIリクエストなどで取得したデータを処理するため、初期表示は若干遅くなります。

![Image (fetched from Gyazo)](https://t.gyazo.com/teams/diverta/d45bf1e4ff5167294faee1777ca641db.png?witdh=600)
<!---
@startuml
"ブラウザ" -> "HTTPサーバー" : リクエスト
activate "HTTPサーバー"
"HTTPサーバー" -> "ブラウザ" : HTMLを返却
deactivate "HTTPサーバー"

"ブラウザ" -> "HTTPサーバー" : リクエスト
activate "HTTPサーバー"
"HTTPサーバー" -> "ブラウザ" : JS/CSSを返却
deactivate "HTTPサーバー"

"ブラウザ" -> "HTTPサーバー" : APIリクエスト
activate "HTTPサーバー"
"HTTPサーバー" -> "ブラウザ" : データを返却
deactivate "HTTPサーバー"

"ブラウザ" -> "ブラウザ" : レンダリング
@enduml
-->

画面遷移やボタンを押したりするイベントが発生した際には、必要に応じてクライアントがサーバーに対してリクエストを行います。リクエストは不要で、JavaScriptだけで画面遷移のような処理を行う場合もあります。サーバーはリクエストに対する最低限のデータだけを返却して、クライアントにて描画します。差分だけなので、2回目以降の表示処理は高速です。

![Image (fetched from Gyazo)](https://t.gyazo.com/teams/diverta/45aaeb2f830f8dab04251d9cab01e590.png?witdh=600)
<!---
@startuml
"ブラウザ" -> "HTTPサーバー" : APIリクエスト
activate "HTTPサーバー"
"HTTPサーバー" -> "ブラウザ" : データを返却
deactivate "HTTPサーバー"

"ブラウザ" -> "ブラウザ" : 表示差分更新
@enduml
-->

## SSG

SSGはStatic Site Generationの略になります。サーバー側で、あらかじめ静的なHTMLやJavaScript、CSSを生成しておくのが特徴です。あらかじめコンテンツを生成し、そのコンテンツをCDNに登録します。そのため、初回に限らず表示処理が高速です。

![Image (fetched from Gyazo)](https://t.gyazo.com/teams/diverta/301b21eebaa0d649a9c52bfae8d5694e.png?witdh=600)
<!---
@startuml
participant "ブラウザ" order 10
participant "HTTPサーバー" order 30
participant "CDN" order 20
"HTTPサーバー" -> "HTTPサーバー" : HTML/JS/CSSを生成
"HTTPサーバー" -> "CDN": HTML/JS/CSSを登録
"ブラウザ" -> "CDN": リクエスト
activate "CDN"
"CDN" -> "ブラウザ": HTML
deactivate "CDN"
"ブラウザ" -> "CDN": リクエスト
activate "CDN"
"CDN" -> "ブラウザ": JS/CSSを返却
deactivate "CDN"
@enduml
-->

SSGの難点はコンテンツの生成頻度によっては、古いコンテンツのままになってしまう点でしょう。CDNのキャッシュを有効に使うためには、なるべく長いキャッシュを利用しつつも、頻繁にアップデートされるコンテンツを含まないようにするなど、古くならない工夫が必要です。

## SSR

SSRはServer Side Renderingの略になります。CSRがクライアント側だったのに対して、SSRはサーバー側でHTMLを生成します。常にサーバー側で表示するHTMLを生成しますので、常に最新の状態に保てるのがメリットです。ただしコンテンツのキャッシュが難しく、CDNを使っている場合と比べて速度が遅かったり、サーバー側の負荷が大きくなります。

![Image (fetched from Gyazo)](https://t.gyazo.com/teams/diverta/9286be838f80088db7b9a846edbb96b4.png?witdh=600)
<!---
@startuml
"ブラウザ" -> "HTTPサーバー": リクエスト
activate "HTTPサーバー"
"HTTPサーバー" -> "アプリケーションサーバー": リクエスト
activate "アプリケーションサーバー"
"アプリケーションサーバー" -> "アプリケーションサーバー" : HTML生成
"アプリケーションサーバー" -> "HTTPサーバー" : HTML返却
deactivate "アプリケーションサーバー"
"HTTPサーバー" -> "ブラウザ": HTML
deactivate "HTTPサーバー"

"ブラウザ" -> "HTTPサーバー": リクエスト
activate "HTTPサーバー"
"HTTPサーバー" -> "ブラウザ": JS/CSSを返却
deactivate "HTTPサーバー"
@enduml
-->

## ISR

ISRはIncremental Static Regenerationの略になります。SSRのようにクライアントからのリクエスト時にページを生成するのですが、それをキャッシュして2回目以降のリクエスト時に利用します。SSGの場合、あらかじめすべてのページを生成しますので、ページ数が多いと生成に時間がかかります。ISRの場合、リクエストがあるまではページを生成しませんので、サーバーの立ち上げが高速です。

ISRではキャッシュの有効期限を決められます。キャッシュ生成から時間が経つと、再度サーバー側でページを生成します。

![Image (fetched from Gyazo)](https://t.gyazo.com/teams/diverta/cc479964da7781fbe7c20be294a7ee0a.png?witdh=600)
<!---
@startuml
participant "ブラウザ" order 10
participant "HTTPサーバー" order 30
participant "CDN" order 20

"ブラウザ" -> "HTTPサーバー": リクエスト
note left: 1回目のアクセス
activate "HTTPサーバー"
"HTTPサーバー" -> "HTTPサーバー": HTMLを生成
"HTTPサーバー" -> "ブラウザ": HTMLを返却
"HTTPサーバー" -> "CDN": HTMLを登録
deactivate "HTTPサーバー"
"ブラウザ" -> "HTTPサーバー": リクエスト
activate "HTTPサーバー"
"HTTPサーバー" -> "ブラウザ": JS/CSSを返却
"HTTPサーバー" -> "CDN": JS/CSSを登録
deactivate "HTTPサーバー"
...


"ブラウザ" -> "CDN": リクエスト
activate "CDN"
note left: 2回目以降のアクセス
"CDN" -> "ブラウザ": HTMLを返却
deactivate "CDN"
"ブラウザ" -> "CDN": リクエスト
activate "CDN"
"CDN" -> "ブラウザ": JS/CSSを返却
deactivate "CDN"
@enduml
-->
