先月2/18にNext.js 12.1がリリースされました。
そのなかでも待望の機能がOn-demand ISR(Beta)です。
この機能が如何に待ち侘びられていたかは公式からも伺えます。
This was one of our most requested features since we introduced Incremental Static Regeneration (ISR) in Next.js 9.5.
出典:https://nextjs.org/blog/next-12-1
On-demand ISR(Beta)の登場で何がどう変わったのか簡単にお伝えしたいと思います。
Next.js プレレンダリング概要
Next.jsのプレレンダリングには大きく2種類あり、SSR(サーバーサイドレンダリング)とSG(静的生成)に分けられます。そして両者のいいとこ取り的なISR。 基本となるCSRを含め簡単に解説します。
CSR (Client Side Rendering)
CSRはユーザーリクエスト時にAPI通信を必要としない部分をプレレンダリングし、ページが読み込まれた後にブラウザ側でAPI通信でデータを取得し表示させる。 一般的なローディング画面があるようなページといえば分かりやすいかもしれない。 CSRはページ遷移自体は高速に行えるが、動的な表示まではローディングの時間が存在します。JavaScriptでの処理が重くなったり、またSEO的にも動的な内容は反映されないことがデメリットと言えます。
SSR (Server Side Rendering)
CSRでは主なHTML生成をJavaScriptで行っていたが、これをサーバー側で行うのがSSRです。ユーザーリクエストごとにサーバー側で動的にHTMLを生成しレスポンスとして返すことでSEOにも反映されます。しかしユーザーリクエスト⇒API通信⇒HTML生成⇒レスポンスといった処理をサーバー側で行う為、表示するページがAPI通信を必要とする場合は特に初回表示に時間がかかることがデメリットとして挙げられます。
SG (Static Generation)
SGはSSRのレスポンスが遅くなる問題を解決します。デプロイ(build)時にAPI通信を含め静的なHTMLを生成しユーザーリクエストのたびにデプロイ時に生成した静的ページをレスポンスとして返します。これによりユーザーリクエストに対し高速なレスポンスが可能になった一方、今度は一度デプロイしたページを動的に変更することができなくなってしまいました。
ISR (Incremental Static Regeneration)
SSR、SG両者を良いとこ取りしたのがISRです。SGの表示の速さを維持しながらSSRのように動的にHTMLを生成したいという無茶振りを解決します。 といっても実装は簡単でSG設定時に「revalidate:秒数」を指定します。 この辺は少しややこしいのですが、正確さを犠牲に簡単に説明すると、通常はSGと同じく事前に生成された静的ページを高速で返しつつ、revalidateで設定した秒数経過後に再度リクエストがあった際は新たにHTMLを生成します。 (秒数経過後の最初のリクエストは古いHTMLが変えるのですがこの辺は少しややこしいので一旦スルーします。)
on-demand ISR (Beta)
前置きが長くなりましたがやっと本題のon-demand ISR(Beta)です。
Next.js 12.1 で登場On-demand ISR(Beta)は今までのISR の進化版です。 以前まではHTMLを再生成するタイミングはrevalidateにより秒数に縛られ、これが唯一の更新方法でした。 例えばブログサイトにISRを導入し、revalidateを60秒に設定した場合 ブログ記事を更新しても最大60秒間は更新が反映されず、更新前に生成されたHTMLがキャッシュとして返ってきます。 更新されたHTMLがrevalidateで設定した秒数経過後に再度リクエストがあったタイミングで初めて生成されます。
on-demand ISRではユーザー側のアクションでunstable_revalidate()を実行することで任意のタイミングでキャッシュのパージとページの再生成を行うことができます。 ブログサイトの例だとブログ記事更新or投稿されたタイミングでunstable_revalidate()を実行するように設定するとSGでありながら常に最新のデータを表示することが可能になります。
さいごに
2週間ほど前にリリースされた機能のため完全には理解できてないので、今後より様々な情報が出てくることを期待しています。
分かりやすさ重視のため一部表現に正確ではないものが含まれる可能性があります。
Next.js https://nextjs.org/
Next.js 12.1 https://nextjs.org/blog/next-12-1