SSG

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

SSG を分かりやすく

さて、今回のトピックは「SSG」、つまり「静的サイト生成」ですね。ここではNext.jsとの関連で話を進めていきましょう。

SSGはウェブサイトを作る手法の1つで、名前の通り静的なサイトを生成します。どういうことかというと、サイトの全ページが予め生成されて、それがそのままブラウザに配信されるんです。これだと、サーバーへのリクエストが来たときに都度ページを作る必要がないので、ページの読み込みが高速なんですよね。それに、セキュリティも強化されます。

例え話で考えてみると、レストランに行って料理を注文するのが通常のサーバーサイドレンダリング(SSR)のやり方と考えると、SSGは、あらかじめ作られたお弁当をすぐに手に入れるような感じです。注文を受けてから料理を作るよりも、予め作っておいたお弁当を提供した方が早いですよね。それと同じで、SSGはあらかじめ生成しておいたページを提供するから早いんです。

でも、SSGだと、全てのページをビルド時に生成しないといけないから、サイトの規模が大きくなると時間がかかると思うんですよね。でも大丈夫!Next.jsでは、ISR(Incremental Static Regeneration)という機能を提供してくれるんですね。これを使うと、一部のページだけを後から静的に生成したり、更新したりできるんです。なんて便利なんでしょう!

一体どういうことなん?って思いますよね。だけど、この手法を使うと、ウェブサイトの表示速度が早くなり、ユーザーエクスペリエンスが向上するんです。それに、Next.jsのISRを使えば、大規模なサイトでも効率的に取り組めます。凄くないですか?ここまで大丈夫ですか?SSG、ぜひ使ってみてくださいね、めっちゃ便利なんですよ!

まとめ

「SSG」とは、「Static Site Generation(静的サイト生成)」の略称です。スタティック・サイト・ジェネレーションと呼びます。この技術は、Next.js や TypeScript を使った Web 開発において重要な役割を果たしています。

例えば、あなたが、クイズに出題する問題集の Web サイトを作りたいと思っているとします。問題集のコンテンツは、クイズの問題とその解答が含まれる HTML ページの集合です。このようなサイトを作るために、静的サイト生成を利用することができます。

具体的には、まず、TypeScript と Next.js を使って、問題と解答が含まれるデータを配列で定義します。以下は、questions.tsというファイルに問題のデータを定義する例です。

export const questions = [
  {
    id: 1,
    question: '1 + 1 = ?',
    answer: '2',
  },
  {
    id: 2,
    question: '2 + 3 = ?',
    answer: '5',
  },
  {
    id: 3,
    question: '5 - 2 = ?',
    answer: '3',
  },
  // 以下、問題と解答のデータが続く
]

実装

次に、このデータをもとに、各問題の HTML ページを生成します。ここで、Next.js の静的サイト生成機能を利用すると、問題と解答が含まれる HTML ページを一括で生成することができます。以下は、generatePages.tsというファイルに、静的ページ生成のためのコードを記述した例です。

import { questions } from './questions'
import { promises as fs } from 'fs'
import path from 'path'
import { NextConfig } from 'next'

export async function generatePages() {
  const outDir = NextConfig().outDir ?? 'out'
  const pagesDir = path.join(process.cwd(), outDir, 'questions')

  await fs.mkdir(pagesDir, { recursive: true })

  for (const question of questions) {
    const html = `
      <html>
        <head>
          <title>問題 ${question.id}</title>
        </head>
        <body>
          <h1>問題 ${question.id}</h1>
          <p>${question.question}</p>
          <hr>
          <h2>答え</h2>
          <p>${question.answer}</p>
        </body>
      </html>
    `
    await fs.writeFile(path.join(pagesDir, `${question.id}.html`), html)
  }
}

このコードでは、まずquestions.tsから問題と解答のデータを読み込み、out/questionsというディレクトリを作成します。

次に、問題と解答のデータをもとに、各問題の HTML ページを生成します。生成されるページのファイル名は、問題の ID に対応した数字で、例えば問題 1 のページは1.htmlというファイル名になります。生成されたページは、out/questionsディレクトリに保存されます。

最後に、静的ページの生成を実行するためのコードをindex.tsファイルに書きます。以下は、index.tsファイルに記述したコードの例です。

import { generatePages } from './generatePages'
;(async () => {
  await generatePages()
  console.log('静的ページの生成が完了しました!')
  process.exit(0)
})()

このコードでは、generatePages()関数を呼び出して、静的ページの生成を実行しています。生成が完了したら、コンソールにメッセージを表示してプログラムを終了します。

以上のように、TypeScript と Next.js を使った静的サイト生成の例を紹介しました。このように、静的サイト生成を利用することで、問題集のようなコンテンツを効率的に生成することができます。また、静的サイト生成は、サーバーの負荷を軽減することができるため、Web サイトのパフォーマンスを向上させることができます。