目次
- SSGの仕組み
- SSG導入のメリット
- SSG導入のデメリット
- SSR(Server Side Rendering)
- ISR(Incremental Static Regeneration)
- CSR(Client Side Rendering)
- レンダリング手法の選択基準
- コンテンツの更新頻度が低いサイト
- パフォーマンス(表示速度)が重要視されるサイト
- SEO効果を高めたいサイト
- セキュリティ性が求められるサイト
- 大量のトラフィックが予想される、または急なアクセス増に対応したいサイト
- 運用コストを抑えたいサイト
- 外部データを使用しないページ
- 外部データを使用するページ
- getStaticPathsを利用した動的ルーティングの静的生成
- ビルド時間への対策
SSGとは
SSG(Static Site Generation)は静的サイト生成と呼ばれるレンダリング手法です。仕組みやメリット、デメリットについて紹介します。
SSGの仕組み
SSGは、ウェブサイトを公開する前に各ページをHTMLファイルとして事前に生成するレンダリング手法です。
Next.jsでSSGを行うページの場合、 next build コマンドを実行するとビルド処理が始まります。この処理の中で、ページを表示するのに必要なデータがヘッドレスCMS、ローカルファイル、APIなどから取得されます。
データが必要なページをHTMLファイルとして事前に生成(レンダリング)することにより、ユーザーがアクセスした際に表示時間を短縮することができる仕組みになっているのです。
表示パフォーマンスの最適化とCDNの役割
SSGで生成された静的ファイルのパフォーマンスを最適化する上で、CDN(Content Delivery Network)は重要な役割を果たします。
通常、ウェブサイトのデータはオリジンサーバーに保存されており、世界中からアクセスが集中します。サーバーから物理的に遠いユーザーにとってはネットワーク遅延(レイテンシー)の原因となり、また、アクセスが集中した際にはサーバー全体の応答速度が低下する要因にもなります。
CDNではオリジンサーバーのデータのコピー(キャッシュ)を、世界各地に配置された「キャッシュサーバー(エッジサーバーとも呼ばれる)」に保存します。
ユーザーがウェブサイトへアクセスすると、CDNはユーザーに最も近いキャッシュサーバーを自動で判別し、そこからデータを送信します。これにより、ユーザーとサーバー間の物理的な距離に起因するネットワーク遅延(レイテンシー)が最小限に抑えられ、表示速度が向上します。
SSG導入のメリット
SSGを導入することによる主なメリットは、表示速度の向上、スケーラビリティの確保、そしてSEO対策の強化です。以下で詳細に説明します。
表示速度
SSGはパフォーマンスの観点から多くの利点を持ちますが、中でも特にユーザー体験に大きく影響するのが、表示速度の向上です。
各ページが事前にHTMLファイルとして生成されるため、サーバーは要求に応じて完成されたページを返す仕組みとなっています。これにより、サーバー側での複雑な処理やデータベースへの問い合わせが不要となるため、ページの初期表示にかかる時間が大幅に短縮され、ユーザーはコンテンツを快適に閲覧できます。
スケーラビリティ
スケーラビリティ(拡張性)とは、アクセスが集中した場合でもサービスを安定して提供できる能力のことを言います。
従来のウェブサイトではアクセスが集中すると、サーバー負荷が高まり表示速度が低下します。場合によってはサーバーダウンを引き起こす可能性もあります。
一方、SSGで生成された静的ファイルはCDNを通じて世界中の多数のエッジサーバーに複製・配置することが可能です。ユーザーからのリクエストは一台のオリジンサーバーに集中することなく、各エッジサーバーへと効率的に負荷分散されます。
何万、何十万という規模の同時アクセスが発生したとしても、サーバーを増強する必要もなく、低コストで大量のトラフィックに対応できます。
SEO対策
SSGではページがビルド時に完全なHTMLとして事前に生成されます。このため、検索エンジンのクローラーはJavaScriptの実行を待つ必要がなく、コンテンツを直接解釈してページ構造やテキスト情報を正確にインデックス化できます。これにより、ウェブサイトの内容が検索結果へ適切に反映されやすくなります。
加えて、SSGのもう一つの強みである高速なページ表示も重要です。快適なユーザー体験を提供するウェブサイトはランキングで優遇される傾向にあるため、表示速度の速さは間接的にSEO評価を高める要因となります。
SSG導入のデメリット
SSGには多くのメリットがある一方、気を付けるべきポイントや欠点もいくつか存在します。
動的コンテンツへの対応
コンテンツの更新があった場合、その変更をウェブサイトに反映させるためにサイト全体の再ビルドが必要になります。
CMSなどでコンテンツを更新しても、ウェブサイト上で公開されているHTMLファイルが更新されるわけではありません。そのため、手動もしくはCI/CDパイプラインなどを通じてビルドを再度実行する必要があります。
頻繁な更新が発生するサイトでは運用しづらく、課題となる可能性があります。
ビルド時間
SSGではビルド時にすべてのHTMLファイルを生成するため、ウェブサイトのページ数が多い大規模サイトだと、処理時間が長くなる可能性があります。
ページ数やコンテンツの複雑さに比例してビルド時間は増大する傾向にあり、数千、数万ページ規模のサイトでは、開発のボトルネックとなることも考慮しなければなりません。
ビルド後の新規コンテンツ
ビルド完了後に新しく追加されたコンテンツ(新しいブログ記事など)は、次のビルドが行われるまでサイトに反映されません。その間、ユーザーは新しいコンテンツを閲覧できない状態になるため、 リアルタイム性が求められる場合は不向きと言えます。
レンダリング手法の比較
Next.jsではSSG以外にも利用可能なレンダリング手法があります。それぞれのレンダリング手法の特徴を理解し、プロジェクトの要件に合った最適なものを選択することが重要です。
SSR(Server Side Rendering)
SSRは、ユーザーからリクエストがあるたびに、サーバー側でHTMLを動的に生成してクライアントに返す手法です。
常に最新のデータを反映したページを表示できるため、頻繁にデータ更新が発生するウェブサイトに適しています。また、ユーザーごとに表示内容が異なる場合も有用です。
SSRとSSGの違い
SSGがビルド時に全ページを準備するのに対し、SSRはリクエスト時に都度ページを準備する点が大きな違いです。そのため、SSGほどの表示速度は期待できない場合もありますが、データ鮮度の観点ではSSRが有効です。
ISR(Incremental Static Regeneration)
ISRは、SSGの利点を活かしつつ、更新の課題に対応するためのNext.js独自のレンダリング手法です。
ビルド時にページを生成した後も、一定間隔(例えば60秒ごと)でバックグラウンドでページを再生成し、キャッシュを新しいものに置き換えます。生成されていないページへのアクセスがあった場合に、オンデマンドでページを生成することも可能です。
ISRとSSGの違い
SSGの「ビルド後にコンテンツを更新するには再ビルドが必要」というデメリットを緩和し、静的サイトの高速性とコンテンツの鮮度を両立させることを目指した手法と言えます。
CSR(Client Side Rendering)
CSRは、最初に最小限のHTMLとJavaScriptをブラウザに送信し、その後ブラウザ上でJavaScriptが実行されることでページを動的に描画します。一度初期ロードが完了すれば、ページ遷移時の画面更新が高速で、ネイティブアプリのようなリッチなユーザーインターフェースの構築に長けています。
しかし、最初のコンテンツ表示までに時間がかかり、検索エンジンがJavaScriptで生成されたコンテンツを正しく認識しにくい場合があるなど、SEOや初期表示速度の観点ではSSGやSSRに劣る場合があります。
CSRとSSGの違い
SSGではビルド時にHTMLが完成し配信されるため初期表示速度とSEOに有利です。CSRではブラウザでJavaScript実行後にHTML描画されるため動的インタラクションに強いです。
レンダリング手法の選択基準
最適なレンダリング手法は、構築するウェブサイトの特性や要件によって異なります。以下の観点から総合的に判断することが求められます。
コンテンツの更新頻度
週に一度記事を更新するブログであればSSGが適していますが、毎秒株価が変動するような金融情報サイトであればリアルタイム性が求められるため、SSRが適していると言えるでしょう。
データの鮮度
在庫状況やフライトの遅延情報など、データの鮮度が重要な場合はSSRやISRを選択し、データ更新頻度が低い場合はSSGを選択するのが適切です。
数時間程度の遅延が許容できる場合は、ISRを利用してパフォーマンスとデータ鮮度を両立することも可能です。
ユーザー体験 (UX)
LPのように、最初の数秒でユーザーの興味を引きつけなければならないページでは、初期表示速度が非常に重要となり、離脱率を下げるためにSSGやISRが効果的です。
一方で、高度なインタラクティブ性が必要な場合には、CSRが適切な選択肢となることもあります。
SEO
検索順位を上げるためには、クローラーがコンテンツを効率的に理解できる必要があります。SSGはHTMLが事前に生成されているため、クローラーがコンテンツを認識しやすく、SEOに有利です。
動的に生成されるコンテンツが多い場合は、適切なメタタグや構造化データを設定することでSSRでもSEO効果を期待できます。
ビルドコスト vs ランタイムコスト
SSGはビルド時に全ページを生成するため、ページ数が多いとビルド時間が長くなりますが、実行時のサーバー負荷を低く抑えられます。一方、SSRはリクエスト毎にページを生成するためビルド時間は短くなりますが、アクセスが増えるとサーバー負荷が高まります。
したがって、サイト規模やアクセス数に応じて手法を選択する必要があります。例えば、トラフィックの少ない小規模サイトにはSSRが、大規模でアクセスが多いサイトにはSSGが適していると考えられます。
SSGが適しているケース
上記の選択基準を踏まえると、SSG(静的サイト生成)が特にその強みを発揮し、最適な選択肢となるケースは以下のような場合です。
コンテンツの更新頻度が低いサイト
企業のコーポレートサイト、ランディングページ、ドキュメント、個人のポートフォリオサイトなど、情報が頻繁に変わらないサイトはSSGに適しています。
パフォーマンス(表示速度)が重要視されるサイト
ウェブサイトにおいて、ユーザー離脱を防ぐためには表示速度の対応が必要です。SSGで事前にHTMLを生成し、さらにCDN(コンテンツデリバリーネットワーク)からデータを送信することで、サーバー処理時間をほぼゼロにし、高速なページ表示を実現できます。
SEO効果を高めたいサイト
ブログ、ニュースサイト、製品情報サイトなど、検索エンジンからの流入を重視するサイトでは、クローラーがコンテンツを容易に解釈できるSSGが有利です。コンテンツが完全にHTMLに記述されているため、インデックス化がスムーズに進みます。
セキュリティ性が求められるサイト
SSGでは静的なファイルを生成し、表示する仕組みなのでデータベースや複雑なサーバーサイドロジックへの依存が少ないため、サーバーの脆弱性を狙う攻撃を受けるリスクを軽減できます。
大量のトラフィックが予想される、または急なアクセス増に対応したいサイト
静的ファイルはCDNによる分散配信と相性が抜群です。キャンペーンサイトやイベント告知サイトなど、一時的にアクセスが集中する場合でも、サーバーダウンのリスクを抑えつつ安定した配信が可能です。
運用コストを抑えたいサイト
複雑なサーバー管理やデータベース運用が不要なため、静的ホスティングサービスを利用することで、インフラコストを低く抑えることができます。
Next.jsにおけるSSGの実装方法
Next.js(PagesRouter環境)でSSGを実装するための方法を解説します。大きく外部データの有無で方法が異なります。
外部データを使用しないページ
会社概要ページや固定のプライバシーポリシーページなど、外部からのデータ取得が不要で、コンテンツがビルド時に確定しているページは、特別なデータ取得関数なしでもSSGの対象となります。
ページコンポーネントを通常通り作成するだけで、Next.jsはビルド時に静的HTMLを生成します。
// src/pages/about.tsx
const AboutPage = () => {
return (
<main>
<h1>会社概要</h1>
<dl>
<dt>会社名</dt>
<dd>株式会社Example</dd>
<dt>設立</dt>
<dd>2025年1月1日</dd>
<dt>事業内容</dt>
<dd>ウェブサイト制作及び開発</dd>
</dl>
<a href='/'>トップページに戻る</a>
</main>
);
};
export default AboutPage;
外部データを使用するページ
ブログ記事一覧や記事詳細ページのように、外部のヘッドレスCMSなどからデータを取得して表示するページでは、getStaticProps
やgetStaticPaths
の記述が必要になります。
getStaticPropsによるデータ取得
getStaticProps
は、ページファイル内でexportされる非同期関数であり、ビルド時にサーバーサイドで実行されます。この関数内でAPIを呼び出すなどしてデータを取得し、そのデータをpropsとしてページコンポーネントに渡すことで、データを含んだ静的HTMLが生成されます。
// src/pages/blog/[slug].tsx
export const getStaticProps: GetStaticProps<Props> = async () => {
const apiResult = await fetchAllContents();
const contents = apiResult?.data || [];
return {
props: { contents },
};
};
getStaticPathsを利用した動的ルーティングの静的生成
Next.jsでURLが動的に変わるページを静的サイト生成(SSG)する場合には、getStaticPaths
のエクスポートが必須となります。これはビルド時にどのパスでページを作成するかを決定するために必要です。
// src/pages/blog/[slug].tsx
export async function getStaticPaths() {
const allPosts = await fetchAllPostSlugs();
const paths = allPosts.map(post => ({
params: { slug: post.slug },
}));
return {
paths, // 生成するパスのリスト
fallback: false, // pathsに含まれないパスは404
};
}
fallcackオプション
getStaticPaths
のfallbackプロパティは、ビルド時にpathsで指定されなかったパスにアクセスがあった場合の動きを設定するために用いられます。
fallback: false
pathsに含まれないパスへのアクセスに対して、404ページを表示します。
fallback: true
pathsに含まれないパスへのアクセスに対して、データ取得を要する部分以外がレンダリングされたページ(フォールバックページ)を返します。
クライアント側では不完全なHTMLを受け取った後、JavaScriptが実行され、必要なデータの取得とページのレンダリングが行われます。
同時にサーバー側でもバックグラウンドでデータの取得と完全なページのレンダリングが実行されます。サーバー側でのレンダリングが完了すると、そのパスに対応する完全な静的HTMLが生成・キャッシュされ、以降同じパスへのアクセスがあった場合は、生成・キャッシュされた静的なHTMLが即座に返されます。
fallback: 'blocking'
pathsに含まれないパスへの初回アクセス時、サーバーサイドでHTMLが完全に生成されるまでユーザーを待機させます。ページ表示後は静的ファイルとしてキャッシュされます。
ビルド時間への対策
サイト規模が大きくなると、ビルド時間が長くなることは避けられません。 これに対しては、いくつかアプローチや対策が存在します。
ビルド対象ページの絞り込み
getStaticPaths
で返すpathsの数を制限し、よくアクセスされるページや最新のページのみをビルド時に生成し、残りはfallbackに任せる方法です。
分散ビルド
大規模なサイトでは、ビルドプロセスを複数のマシンやコンテナに分散させて並列処理することで、全体のビルド時間を短縮する試みも行われます。
まとめ
本記事では、Next.jsのレンダリング手法の一つ、SSGに焦点を当て、その基本構造から具体的な実装方法、さらには他のレンダリング手法との比較について解説しました。
SSGは、ビルド時にページを静的なHTMLファイルとして事前生成することにより、現代のウェブサイトに求められる多くの要件、例えば表示速度、スケーラビリティ、SEO対策などを満たす強力な手法です。
ウェブサイト開発を成功させるためには、プロジェクトの目的、コンテンツの特性、そしてユーザーに提供したい体験を深く考慮し、これらのレンダリング手法を適切に選択・組み合わせることが重要です。