
Next.jsのISR(Incremental Static Regeneration)でWebサイトを高速化・スマート化する方法
Webサイトを構築する際、ページの生成方法には大きく分けて静的生成と動的生成の2つの選択肢があります。本稿では、Next.jsのISR(Incremental Static Regeneration)という、両者の良いところ取りをした手法について解説します。ISRを利用することで、高速な読み込みと最新コンテンツの提供を両立させることができます。
ISRとは?静的生成と動的生成の良いとこ取り
ISR (Incremental Static Regeneration) は、Next.jsの機能で、サイトをビルドした後でも静的ページを更新できます。従来の静的サイトでは、変更があるたびにサイト全体を再構築する必要がありましたが、ISRはその問題を解決します。
ISRを使うと、Next.jsに一定時間経過後、または必要に応じてバックグラウンドでページを再構築するように指示できます。ユーザーは高速な静的ページを見ることができますが、ページは手動で再構築しなくてもバックグラウンドで自動的に更新されます。
簡単に言えば、ページは事前にレンダリングされ、静的なファイルのように提供されます。 設定された時間が経過すると、Next.jsは最新のデータでページを再生成し、ユーザーは常に高速で信頼性の高いページを取得できます。
ISRの仕組みを徹底解説
ISRを理解するために、まずはNext.jsでページを構築する3つの方法を見てみましょう。
- 静的生成(SSG): ページはデプロイ時に一度だけ構築されます。サイト全体を再構築しない限り変更されません。
- サーバーサイドレンダリング(SSR): ページはリクエストごとに新しく構築されます。サーバーが毎回処理を行うため、速度が遅くなる可能性があります。
- Incremental Static Regeneration(ISR): ページは、設定された時間が経過した後、必要な場合にのみリクエスト時に構築されます。それ以外の場合、ユーザーはすでに構築済みのページを即座に取得します。
ISRの具体的な動作
ISRを使用する場合:
- ユーザーがページにアクセスします。
- ページが既に構築されていて、有効期限が切れていない場合、Next.jsはキャッシュされた静的ページを提供します。
- 設定した時間に基づいてページが期限切れになっている場合、Next.jsは古いページを提供しながらバックグラウンドでページを再構築します。
- 次にアクセスするユーザーは、自動的に最新バージョンを取得します。
getStaticProps
関数内のrevalidate
キーを使用して、ページの有効期限を制御します。
上記設定の場合:
- ページは最初に誰かがアクセスしたときに構築およびキャッシュされます。
- 60秒後、誰かが再度アクセスすると、Next.jsは新しいデータを使用してバックグラウンドでページを再構築します。
- ユーザーは常に即座にページを取得します。待つ必要はありません。
ISRが新しいページ生成をトリガーするのはいつ?
ISRがどのようなものかわかったところで、ページが実際にいつ、どのように再生成されるかを見てみましょう。
- ユーザーがページをリクエストします。
- Next.jsは、キャッシュされた(既に構築済みの)ページが存在するかどうかを確認します。
- ページがまだ「新鮮」な場合(
revalidate
時間内)、キャッシュされたページを提供します。 - ページが「古い」場合(
revalidate
時間外)、古いキャッシュされたページを即座に提供しますが、バックグラウンドでページの再構築も開始します。 - 再構築が完了すると、次のユーザーは新しい更新されたページを取得します。
重要事項: 誰も待つことはありません。 ISRは常に、新しいページまたは以前のバージョンのいずれかを即座に提供します。
ISRの代表的なユースケース
ISRは、以下のような状況において特に有効です。
- ブログやニュースサイト: 新しい記事が頻繁に追加される場合。高速な読み込み速度を維持しつつ、最新のコンテンツを提供できます。
- Eコマースの商品ページ: 価格や在庫状況など、商品情報が頻繁に変更される場合。ショッピング体験を損なうことなく、データ更新を反映できます。
- ダッシュボードやユーザー生成コンテンツ: リアルタイム性がそれほど重要でないダッシュボード、レビュー、フォーラム、ユーザープロファイルなどに適しています。サーバーへの負荷を抑えつつ、定期的にコンテンツを更新できます。
ISRを最大限に活用するためのベストプラクティス
ISRで最良の結果を得るには、正しく設定する必要があります。すべてがスムーズに動作するようにするための重要なヒントをいくつか紹介します。
-
適切な
revalidate
時間を設定する:コンテンツが実際にどのくらいの頻度で変更されるかを検討してください。
- コンテンツが1時間ごとに変更される場合は、
revalidate:3600
(1時間)を設定します。 - コンテンツが毎日変更される場合は、
revalidate:86400
(24時間)を設定します。 - コンテンツが数分ごとに変更される場合は、
revalidate:300
(5分)を設定します。
ヒント: 新しさとサーバー負荷のバランスを取る
revalidate
時間を選択してください。時間が短いほどデータは新しくなりますが、サーバーへの負荷が大きくなる可能性があります。 - コンテンツが1時間ごとに変更される場合は、
-
エラーを効率的に処理する:
ページの再生成時に、データソース(APIなど)が失敗する場合があります。ページが壊れないようにするには:
- 常に
getStaticProps
でtry-catch
ブロックを使用してください。 - フェッチが失敗した場合は、フォールバックメッセージまたは簡単なエラーページを表示します。
- 常に
-
SEOを考慮する:
ISRは静的ページを高速に配信するため、SEOに最適です。
- データフェッチが失敗した場合でも、常に意味のあるコンテンツを返すようにしてください。
- ISRを使用している場合は、「読み込み中…」の状態を表示しないようにしてください。ページはユーザーと検索エンジンの両方にとって完全に完了しているようにする必要があります。
ISRの潜在的な落とし穴とその回避方法
ISRは非常に優れていますが、注意しないとつまずく可能性のある点がいくつかあります。注意すべき点は次のとおりです。
-
古いデータの問題:
ページがまだ再検証されていない場合、ユーザーに古いデータが表示されることがあります。これは、新しいバージョンが構築されるまで、ISRがキャッシュされたバージョンを提供するからです。
対処方法:
- コンテンツに合わせて
revalidate
時間を設定します。 - コンテンツが非常に機密性が高い場合(株価など)、ISRの代わりにサーバーサイドレンダリング(SSR)を使用することをお勧めします。
- コンテンツに合わせて
-
デプロイの誤った構成:
ISRが正しく動作するには、サーバーサポートが必要です。 VercelやNetlifyなどのプラットフォームでサイトをホストする場合、これらは自動的に処理されます。
ただし、カスタムサーバーまたは異なるホスティングを使用する場合は、以下を確認してください。
- サーバーレス関数またはバックエンドサポートが実行されていること。
- 誤ってサイトを静的のみのホスティングにしないこと(バックエンドなしのプレーンなS3バケットなど)。
ヒント: ホスティングプロバイダーのドキュメントを常に確認して、Next.js ISRが適切にサポートされていることを確認してください。
-
大規模な再構築は負荷スパイクを引き起こす可能性があります:
revalidate
が短すぎて、数千のページがある場合、サーバーはバックグラウンド再生成リクエストでいっぱいになる可能性があります。対処方法:
revalidate
値を賢く設定してください。- 非常に大規模なサイトの場合は、オンデマンドISR(ページをいつ手動で再構築するかを制御します。これについては次に説明します)を検討してください。
応用編:オンデマンドISR
通常、ISRでは、revalidate
で定義した設定時間後にページが再生成されます。ただし、完全に制御したい場合があります。次のような場合に、何かが発生した直後にページを再生成したい場合があります。
- 新しいブログ投稿が公開された
- 製品が更新された
- ユーザーが新しいコンテンツを送信する
これが、オンデマンドISRが役立つところです。
オンデマンドISRを使用すると、APIルートを使用してページを再構築するように手動でトリガーできます。タイマーを待つ必要はありません。いつ発生するかを決定します。
オンデマンドISRの設定方法
2つの簡単なことが必要です。
- Next.jsにページを再検証するように指示するAPIルート。
- 誰でもトリガーできないようにAPIを保護するための秘密のトークン。
簡単な例を示します。
トリガー方法
次のように、APIルートにPOSTリクエストを行うことができます。
POST /api/revalidate?secret=YOUR_TOKEN&path=/your-page-path
たとえば:
POST /api/revalidate?secret=MY_SECRET_TOKEN&path=/posts/my-new-post
Next.jsは/posts/my-new-post
をすぐに再構築します。タイマーを待つ必要はありません。
重要事項:
- 常に秘密トークンを使用し、安全な場所に(.envファイルなど)安全に保管してください。
- 信頼できるシステム(CMSや管理パネルなど)のみが再検証APIを呼び出すことができるようにしてください。
まとめ
Incremental Static Regeneration(ISR)は、Next.jsの中でも最高の機能の1つです。静的ページの速度と動的コンテンツの新しさを同時に実現します。
ISRを使用すると:
- ページがすぐに読み込まれます。
- コンテンツは完全な再構築なしに最新の状態になります。
- Webサイトはスムーズでモダンになり、プロフェッショナルに見えます。
ISRを賢く使用すると、複雑にすることなく、より高速でスマートなWebサイトを構築できます。