ダイキのアプリ開発ナレッジ

アプリ開発のナレッジを掲載します

Next.jsのSSG(Static Site Generation)に関する4パターンの整理

Next.js は基本的にデフォルトでビルド時にHTMLを事前生成する
ビルド時にDBからPre-FetchをしてHTMLを事前生成する方式とアプリ運用時のサーバーアクセス時にDBからHTMLを生成する方法が大きく4種類あるので整理する

SSGはStatic Site Generationの略でユーザーに渡す情報は基本的には静的データを渡そうというコンセプトのもとに作られたアプリがユーザーにデータを渡す仕組みである
従来のデータ配信方式ではDBに格納された情報を毎回動的にHTMLにレンダリングして渡していたが、SSGで実装されたアプリでは一度HTMLにレンダリングされた情報は静的コンテンツにしておいて次回のアクセス時には静的コンテンツとして配信される
このHTMLにレンダリングするタイミングの違いによってSSGは以下の4種類のパターンに分類される

SSGについて例えを出すならば今までは飲食店で注文を受けたらその都度料理していたが、開店前に作り置きを作っておいて注文を受けたらそれを出すようなものです
また飲食店は新規メニューのオーダーも都度受け付けていて新規メニューの注文があればその場で料理を行って提供し、その後は作り置きを提供するような仕組みになっています

ISRはIncremental Static Regenerationの略で最新情報をHTMLにレンダリングしておいて静的コンテンツにしておく技術である

ちなみにややこしい話ですがSSRという単語もあって、こちらはServer Side Renderingの略でHTMLは従来クライアント側で生成していたものをサーバ側で作成して渡すようにしたことにあえて名前がついたものになっています
SSRについて例えを出すならば今までコープで食材だけもらって料理は自宅でするのが当たり前だったが生活様式が変化してきてUserEatsを使う人が増えたので"出前"という言葉がはやり始めたみたいな状況です

1.SSG

DocumentやHelpなどのように「完全に静的なページ」
SEOは特に意識しない
代表的なものとしては Index ページがこの実装にあたる場合が多いと思われる
あとはDocumentやHelpページ


2.SSG + Prefetch

ビルド時にデータベースから取得してきた情報を事前にHTMLにレンダリングして静的データとしておくパターンです
Googleクローラーに読み込まれるため、SEO対策に有効です
使われるページの例としてはブログページや商品一覧などが考えられています
ただしそのままだとビルド時の情報のみ使用されるため最新情報を反映させ合たい場合は別途対策が必要です
最新情報を取得する場合にはISRが必要になり、基本的にはISRをセットで利用する場合が多いと思われます
ISRを加えた2.1のパターンがNext.jsで一番よく実装されるであろうと考えられます

2-1. SSG + Prefetch + ISR

Next.jsはビルド時の情報が使われてその後情報が更新されません
後々情報を更新したい場合はISR(DBの最新データで静的サイトを作り直す技術)を使って更新します。
ビルド時にデータを事前にレンダリングするだけでなく、ビルド以降に作成・更新された最新情報に関してもHTML事前レンダリングが実行されて(初回アクセスがトリガー)グーグルのクローラーに分析してもらえるようになり、最新の情報にもSEO対策が施されます


3.SSG + Client side fetching

SEOを意識する必要はないが、最新情報を取得したいページに利用されるパターンです
通常の「create-react-app」(従来のウェブアプリの実装)と似たようなレンダリングの仕組みになります
Client side fetching(通常のAxiosなどのAPI経由でデータを取得する方法)を使って、その都度バックエンドから取得してきたデータをレンダリングしてページを表示させます。
最新データはHTMLにレンダリングされないために新規作成もしくは更新された情報はDBから情報を取得して毎回レンダリングされる仕様となります
DBから情報を取得しないとレンダリングされないのでグーグルのクローラーは有益な情報は何もないと判断してしまい最新の情報に関してはSEOされることはありません
代表的なものとしてはDashboardやTodoリストなどのようなページです


4.SSG + Prefetch + Client side fetching(useSWR)

データをリアルタイムで作成・更新する必要があって、かつ、最新情報にもSEO対策を施す必要があるようなページに利用されるパターンです
2のパターンとほぼ同様ですが、Client side fetchingを使用することで、データの更新をリアルタイムに反映することができます
ただしこの状態では画面表示においてビルド時の過去データと最新情報に乖離がある場合に過去データが表示されたのちに最新データに更新されるという挙動が起きてしまうので、以下の最新データから静的コンテンツを作成しておくISRと組み合わせて使う実装が実用的である

4-1. SSG + Prefetch + Client side fetching(useSWR) + ISR

Next.jsはビルド時の情報が使われてその後情報が更新されません。
後々情報を更新したい場合はISR(DBの最新データで静的サイトを作り直す技術)を使って更新します
ビルド時にデータを事前にレンダリングするだけでなく、ビルド以降に作成・更新された最新情報に関してもHTML事前レンダリングが実行されて(初回アクセスがトリガー)グーグルのクローラーに分析してもらえるようになり、最新の情報にもSEO対策が施されます
初回アクセス以降は事前レンダリングされた最新情報のHTMLが配信されるためISRを使用しないと過去データが表示されたのちに最新データが表示される現象も解決する(具体的にはISRのrevaridateを設定する必要がある)