Web●●●○○

SSG

Static Site Generation ・ えすえすじー

全ページのHTMLをビルド時に作り置く方式。配信が速く、アプリケーションサーバが要らない。

✦ 30秒で試す — 航海アクセスが来たとき、サーバは何も計算しない10万ページのいま、記事1本を直したときの作り直しは?予想してみる

概要

SSG(Static Site Generation、静的サイト生成)は、リクエストが来てからHTMLを作るのではなく、デプロイ前のビルド時に全ページのHTMLをあらかじめ作っておく方式です。アクセスが来たら、できあがったファイルをそのまま返すだけ。サーバ側での計算が一切発生しないため配信は最速クラスで、アプリケーションサーバの運用そのものが不要になります。

MarkdownやCMSのデータを材料に、テンプレートやコンポーネントを通してHTML群を吐き出すツールを静的サイトジェネレータと呼びます。古くはJekyll、現在はAstro・Next.js・Hugo・Eleventyなどが代表格です。ブログ、ドキュメントサイト、コーポレートサイト、そしてこの知星図も、SSGで作られています。

なぜ生まれたか

もともとWebは静的なHTMLファイルの置き場でした。しかし手書きのHTMLでは、ヘッダーを1箇所直すのに全ページを編集する羽目になります。この管理不能さを解決したのが、データベースからHTMLを毎回動的に生成するCMS(WordPressなど)でしたが、今度は別の問題を抱えました。内容が昨日から変わっていないブログ記事のために、アクセスのたびにPHPが走りSQLが発行される。サーバは重く、攻撃対象領域は広く、プラグインの脆弱性やDBの故障が絶えません。

「更新はたまにしかないのに、なぜ毎回作り直すのか。更新のタイミングで一度だけ生成すればいいはずだ」——この割り切りがSSGです。2008年のJekyllとGitHub Pagesの組み合わせが火付け役となり、Gitで原稿を管理してpushしたら自動でビルド・公開、という開発者フレンドリーなワークフローが広まりました。動的生成の柔軟さを手放す代わりに、速度・堅牢性・運用の簡単さを得るという交換です。

詳細

ビルドと配信の二段構え

SSGの世界では、「ページを作る時間(ビルド時)」と「ページを届ける時間(リクエスト時)」が完全に分離されます。ビルド時には、Markdown や CMS のデータを読み、テンプレートやコンポーネントを通して全ページのHTMLを書き出します。リクエスト時には、できあがったファイルを返すだけです。

ビルド時更新のときだけ走るリクエスト時アクセスのたびに走る原稿を更新git pushCIがビルド実行全ページのHTMLを生成配置CDN唯一の接点ブラウザの要求生成済みHTMLを即返すリクエスト時に走る計算はゼロ
ビルド時とリクエスト時という2つの時間は完全に分離され、CDNに置かれたファイルだけが接点になる

2つの時間はCDNに置かれたファイルだけでつながっており、リクエスト時に走る計算はゼロです。

重い処理(データ取得、テンプレート展開、最適化)はすべてビルド時に済んでいるので、リクエスト時にはもう何も考えることがありません。この単純さは性能だけでなくセキュリティにも効きます。リクエスト時にサーバで実行されるコードが存在しないため、SQLインジェクションのようなサーバ側の脆弱性が原理的に成立しないのです。ただし、ブラウザで動く JavaScript やフォームの送信先の API には従来どおり気を配る必要があり、「静的だから安全」は配信の部分に限った話です。

CDNとJamstack

生成物がただのファイルであることは、CDNとの相性が抜群であることを意味します。世界中のエッジサーバにHTMLを複製しておけば、どこからのアクセスにも近距離で応答でき、オリジンサーバは不要です。この「静的配信 + 必要な動的機能はAPIで後付け」という構成はJamstackと呼ばれ、Netlify・Vercel・Cloudflare Pagesといったホスティングサービスが、Git連携からCI/CDによるビルド、CDN配信までを一体で提供しています。コメント欄や検索のような動的要素は、ブラウザ上のJavaScriptから外部APIを呼ぶ形で組み込みます。

制約: 更新はビルド待ち、ページ数はビルド時間

SSGの弱点は「内容の鮮度」と「規模」に集約されます。内容を1文字直すだけでも再ビルドと再デプロイが必要で、反映まで数分のタイムラグが生まれます。リクエストごとに内容が変わるページ——ログインユーザーのマイページ、リアルタイムの在庫表示——はそもそも作り置きできません。また、ページ数が数万〜数百万に達すると、全ページの事前生成はビルド時間の爆発を招きます。「更新頻度が低く、全員に同じ内容を見せる、規模が現実的なサイト」がSSGの適地であり、そこから外れるほどSSRやクライアント側での描画に軍配が上がります。

SSRとの中間解

この境界を柔らかくする手法も発達しています。代表が ISR(Incremental Static Regeneration。Next.js が2020年に導入)で、生成済みの静的ページを配信しつつ、決めた時間が過ぎたあとの最初のアクセスをきっかけに裏側で再生成して差し替えます。古いページを返しながら新しいページを作るので、読者は待たされません。時間で区切る代わりに、CMS の更新通知を受けてそのページだけを作り直す「オンデマンド再検証」もあります。「ほぼ静的だが、たまに新しくなる」ページ(ニュース一覧やECのカタログ)や、数十万ページのうちよく読まれるものだけを先に作りたいサイトに有効です。

また、Astroなどの現代的フレームワークはページ単位でSSGとSSRを混在でき、「基本は静的、動的が必要なページだけサーバレンダリング」という構成が標準になりつつあります。なお、SSG で作ったページでも、ボタンやフォームを React などのコンポーネントで書けば、ブラウザでのハイドレーションは SSR と同じように必要です。配信が速いぶん画面が見えるのは早く、そのぶん「見えるのに効かない」時間が目立ちやすくなります(SSR の記事の部品で、SSG を選ぶと確かめられます)。SSGかSSRかは二者択一ではなく、ページごとの更新頻度とパーソナライズの要否で使い分けるグラデーションとして捉えるのが現代的な理解です。

試問

Web サイトのページを、どの作り方で届けるかを決めます。SSG はデプロイ前のビルドで全ページの HTML を作り置き、ISR は作り置いたページを配りながら、決めた時間が過ぎたら裏で作り直して差し替えます。どちらにも向かないページは、リクエストが来るたびにサーバやブラウザで組み立てます。

✦ 命題挑戦中

8つのページを、SSG で作り置く・ISR で時々作り直す・リクエストごとに組み立てる、のどれが向くかで仕分けよ

SSG で作り置くビルドのときに一度だけ作る
ISR で時々作り直す作り置きを配り、裏で差し替える
リクエストごとに組み立てる見る人・瞬間ごとに違う

項目を選んでから、入れる箱を選びます