Blog Article
SSR / SSG / ISR の違い

はじめに
Next.js を学び始めると、必ずと言っていいほど出てくる言葉が SSR、SSG、ISR です。多くの解説では「高速」「SEO に強い」「再生成」といった断片的な説明が並びますが、初学者にとっては違いが非常に分かりづらい概念です。
この記事では、SSR / SSG / ISR の違いを「ページの HTML をいつ作るか」という 1 点に絞って説明します。技術的な用語はできるだけ噛み砕き、アクセスされたときに内部で何が起きているのかを、流れとして理解できることを目標にします。
参考にしたリンク
- https://nextjs.org/docs/app/building-your-application/rendering
- https://nextjs.org/docs/app/building-your-application/data-fetching
SSR / SSG / ISR の共通点
SSR、SSG、ISR はすべて「ブラウザに返す HTML を生成する方法」です。JavaScript の実行方法や React の書き方が変わるわけではなく、「HTML をいつ作るか」だけが異なります。
Next.js では、最終的にユーザーのブラウザに HTML を返します。この HTML がどのタイミングで作られたのかによって、SSR、SSG、ISR という名前が付いています。
SSR とは何か
一言で言うなら、SSR は「アクセスされるたびに HTML を作る方法」です。
SSR では、ユーザーがページにアクセスした瞬間に、サーバー上で HTML が生成されます。つまり、アクセスがあるたびに毎回 HTML を作り直しています。
アクセスの流れ
ユーザーが URL にアクセスすると、そのリクエストは Next.js のサーバーに届きます。サーバーはそのリクエストを受け取ってから、必要なデータを取得し、React コンポーネントを実行し、その結果として HTML を生成します。その HTML がそのままブラウザに返されます。
この一連の処理は、毎回のアクセスごとに必ず行われます。
[ ユーザー ]
↓ アクセス
[ Next.js サーバー ]
↓ fetch 実行
[ API / DB ]
↓ データ取得
[ Next.js サーバー ]
↓ HTML 生成
[ ユーザー ]ユーザーのリクエストが来てから、初めて fetch が実行され、HTML が作られます。
そのため、常に最新の情報を反映できますが、毎回処理が発生する分、サーバー負荷は高くなります。
なぜ SSR が必要なのか
常に最新のデータを表示したい場合、SSR は非常に有効です。
SSR がなければ、ユーザーごとに異なる情報を安全に表示することが難しくなります。
SSG だと、ユーザーごとの情報が扱えなかったり、最新状態が反映できないからです。
- マイページ
- 管理画面
- ユーザーごとに内容が変わるページ
- 常に最新データが必要なページ
などのページに使われています。
SSR の実装例
SSR は特別な設定をしなくても実現できます。キャッシュを無効化した fetch を使うことで、リクエストごとに実行されます。
Next.js で SSR になる条件は以下のとおりです。
cache: "no-store"を使うdynamic = "force-dynamic"- Cookie / Header を使う
export default async function Page() {
const res = await fetch('<https://example.com/api/posts>', {
cache: 'no-store',
})
const posts = await res.json()
return <div>{posts.length}</div>
}この場合、アクセスされるたびに fetch が実行され、HTML が生成されます。
SSG とは何か
一言で言うなら、SSG は「ビルド時に HTML を作っておく方法」です。
SSG では、ユーザーがアクセスする前に、すでに HTML が作られています。npm run build などのビルドコマンドを実行したタイミングで HTML が生成されます。
アクセスの流れ
ユーザーがページにアクセスすると、サーバーはすでに存在している HTML ファイルをそのまま返します。サーバー上で新たに計算やデータ取得は行われません。
このため、非常に高速にページが表示されます。
[ ビルド時 ]
↓ fetch 実行
[ API / DB ]
↓ データ取得
[ HTML を事前生成 ]
[ ユーザー ]
↓ アクセス
[ 生成済み HTML ]
↓
[ ユーザー ]ユーザーがアクセスした時点では、fetch は一切実行されません。完成済みの HTML を返すだけなので、非常に高速です。
なぜ SSG が必要なのか
ブログ記事や会社紹介ページなど、頻繁に内容が変わらないページでは、毎回 HTML を作り直す必要がありません。SSG を使えば、サーバーの負荷を大きく減らすことができ、表示速度も向上します。
SSG がなければ、すべてのページで SSR を行う必要があり、無駄な処理が増えてしまいます。
- ブログ記事
- お知らせ
- 会社概要
- 利用規約
などの、内容がほとんど変わらないページに使用されます。
SSG の実装例
SSG はデフォルトの fetch を使うことで実現できます。
SSG では、ビルド時に fetch が実行され、その結果を元に HTML が生成されます。ビルド後は fetch は実行されず、生成済みの HTML が返されます。
export default async function Page() {
const res = await fetch('<https://example.com/api/posts>')
const posts = await res.json()
return <div>{posts.length}</div>
}この fetch はビルド時に実行され、その結果が HTML として保存されます。
ISR とは何か
一言で言うなら、ISR は「一定時間ごとに HTML を作り直す方法」です。
ISR では、最初は SSG と同じくビルド時に HTML が作られます。しかし、指定した時間が経過すると、次のアクセスをきっかけに HTML が再生成されます。
アクセスの流れ
最初のアクセスでは、すでに作られている HTML が返されます。指定した時間が経過した後にアクセスがあると、そのリクエストをきっかけに裏側で新しい HTML が作られます。
この間も、ユーザーには古い HTML が返されるため、表示が遅くなることはありません。
[ ビルド時 ]
↓ fetch 実行
[ HTML を事前生成 ]
[ ユーザー ]
↓ アクセス
[ キャッシュされた HTML ]
↓
[ ユーザー ]
( 一定時間経過後 )
[ ユーザー ]
↓ アクセス
[ Next.js サーバー ]
↓ 裏側で fetch 実行
[ HTML を再生成 ]ユーザーには常に HTML が即時返されますが、裏側では新しい HTML が更新されていきます。
なぜ ISR が必要なのか
SSG は高速ですが、内容を更新するたびにビルドが必要です。ISR を使えば、頻繁なビルドなしに、ある程度新しい情報を表示できます。
ISR がなければ、「高速」か「最新」のどちらかを諦める必要がありました。
- SSG は更新が反映されない
- SSR は遅くて重い
👉 その中間を取るのが ISRです。
- ブログ
- ニュース
- 商品一覧
- 更新頻度は低いがゼロではないページ
などに使用されます。
ISR の実装例
ISR では fetch に revalidate を指定します。これにより、一定時間キャッシュされた HTML が有効になります。
export default async function Page() {
const res = await fetch('<https://example.com/api/posts>', {
next: { revalidate: 60 },
})
const posts = await res.json()
return <div>{posts.length}</div>
}この場合、HTML は 60 秒間キャッシュされ、その後のアクセスをきっかけに再生成されます。
いつどれを使うのか
ここまでの内容を踏まえると、選択基準は非常にシンプルです。
- 常に最新の情報が必要なページは SSR
- 内容がほとんど変わらないページは SSG
- 更新頻度はあるが即時性は不要なページは ISR
まとめ
種類 | HTML を作るタイミング | fetch の実行タイミング | 向いているページ |
|---|---|---|---|
SSR | アクセス時 | 毎回 | ダッシュボード、管理画面 |
SSG | ビルド時 | 1 回のみ | ブログ、LP |
ISR | 一定時間ごと | 再生成時 | ニュース、一覧ページ |
SSR / SSG / ISR の違いは、内部処理を細かく覚えることではなく、「HTML をいつ作るか」という軸で理解することが重要です。