目的
Next.jsのISRはどのような動作をするのかを、正しく理解したい!
ISRとは
ISR(Incremental Static Regeneration)とは、SSGを利用しながらも、一定時間ごとにデータの再取得を行い、HTMLを再生成する手法のことを指します。
ISGとの違い
ISRを調べていると、ISGという単語が一緒に出てくることがあります。
ISG(Incremental Static Generation)とは、Dynamic Routesのページにアクセスした際に、オンデマンドでページ生成を行う手法のことを指していたようです。
この単語は公式ドキュメントには現在明確には記載されている箇所はありません(おそらく…)。ドキュメント内に貼られているサンプルサイトを確認すると、ISGに関する記載が少しだけ残っています。
Dynamic RoutesのキーがツイートIDなどの場合、パターンが膨大すぎてそれらを事前にビルドすることは不可能なので、アクセスがあったタイミングで生成を行う必要があります。そのような場合にISGは有効です。
これはgetStaticPaths
の中のfallback: true
もしくはfallback: 'blocking'
オプションを設定することで実現できます。
(fallbackオプションの違いはこの記事がわかりやすいと思います。)
ISG(fallback)はDynamic Routesのページにアクセスした際の挙動を設定するもので、ISR(revalidate)は、ページ再生成の間隔を設定するものとなります。SSGとSSRのような二者択一的なアプローチではないので、そこは正しく理解をしたいです。
(fallback:false
,fallback:true
,fallback:'blocking'
いずれも、ISRを有効にすることは可能です。)
現在はISRという概念に、fallbackオプションも含有されたような位置付けになっているようです。(Vercel – Incremental Static Regeneration - Vercel Documentation)
ISRの用途
ISRを有効にしたとしても、revalidate
で設定した秒数が経過するまでは、古い情報が返されることになるので、常に最新の情報を表示する必要があるシステムには向いていません。
またウェブメディアのような、ユーザー生成のコンテンツではなく、更新頻度もそこまで多くないシステムであれば、通常のSSGで事足りてしまうでしょう。
そんなことを考えると、意外とISRの出番って無いのでは?と思いましたが、プログラマ向け情報共有サービスのZennではISRを採用していた実績があるようです。(Next.jsのISRで動的コンテンツをキャッシュするときの戦略)
ユーザー生成でコンテンツ更新がそこそこの頻度であるものの、必ずしも最新であることは求められないシステムになるかと思うので、まさにISRがフィットする事例だと思います。
※インフラをVercelからGCPへ移行した関係で、現在はISRは使用していないようです。
サンプルサイト
今回ISRの挙動をわかりやすくするため、サンプルサイトを作成してみました。このサイトを見てもらえれば、ISRの挙動が理解できると思います。
再生成までの時間は20秒で設定しているので、次にHTMLが生成されるのは、「HTML created time」の20秒後以降にアクセスしたタイミングとなります。
その際ファイルの再生成は行われますが、レスポンスは再生成前の古いHTMLが返ってくる点がポイントです。
また、再生成もサーバーサイドで処理を行う必要があるため、完了までには若干の時間を要します。再生成完了までは、アクセスしても古いHTMLが返ってくるので注意したいです。
サンプルコード
上記サイトは同時アクセスされている場合、挙動がわかりづらくなります。その場合は以下ソースコードをクローンして、ローカルで実行していただくとわかりやすいかと思います。
yarn dev
で起動するとSSRで動作してしまうので、yarn build
→yarn start
を利用してください。