見出し画像

Next.jsのISRを利用して定時更新する静的ページを作る

Next.js が去年リリースした機能の一つに ISR = Incremental Static Regeneration という機能があります。

ISR を使うことで、レンダリング済みの html を高速に返却するという SSG の恩恵を受けながら定期的に静的ページを更新することができます。

リリースからそこそこ経つ機能ですが、 ISR の具体的なユースケースに沿った解説をあまり見かけなかったため、毎時0分に更新するページを例に解説したいと思います。

ISRとは

ISR = Incremental Static Regeneration(インクリメンタル静的再生成)。

ページへの初回アクセス時に初めて静的ページを生成し、以後指定の秒数以内のアクセスをトリガーに静的ページを再生成します。

静的ページを返す秒数の指定の方法

export const getStaticProps = async () => {
 const articles = await fetchArticles()

 return {
   props: { articles },
   revalidate: 1, // ここ!
 }
}

毎時0分に更新するページを設定するには

実装内容としては非常にシンプルで、初回アクセス時に次の更新時間までの秒数を計算して getStaticPropsrevalidate に渡すだけです。

import { differenceInSeconds, startOfMinute, addMinutes } from "date-fns";

export default function Index({ time, diff }) {
 return (
   <div style={{ border: "1px solid black", padding: "10px", margin: "10px" }}>
     <p>現在時刻は{time}です。</p>
     <p>次の更新まで{diff}秒です。</p>
   </div>
 );
}

export async function getStaticProps() {
 const time = startOfMinute(new Date());

 const now = new Date();
 const next = startOfMinute(addMinutes(now, 1));
 const diff = differenceInSeconds(next, now);

 return {
   props: { time: time.toLocaleString(), diff },
   revalidate: diff > 0 ? diff : 1,
 };
}

確認しやすくするため、毎時0分ではなく毎分0秒に更新されるように設定します。

結果

初回アクセス時に表示されたページと、0秒を過ぎた後にアクセスしたページ。

画像1

画像2

0時を過ぎるまでは表示が変わることはありませんでしたので、成功です。

注意点

唯一、残念なのが再生成が行われるトリガーになるアクセスは前回生成された静的ページが表示されるため、更新時刻後最初のアクセスでは古いページが表示されてしまいます。

これを回避するために Cron などで定時にアクセスして再生成を促してあげる必要があります。

また、 ISR の実行には next start を実行できる環境が必要になります。

まとめ

Next.js の ISR の実装によって、 SSG の恩恵を受けることができるユースケースが増えました。ユーザーにとっても運営側にとてもいい機能だと思います。

ここまで読んでいただきありがとうございます。この機能を使うことで幸せになるWebサイトが増えますように。

もし更新時刻以後のアクセスで古いページを表示しなくていい方法をご存知の方は教えていただければとても嬉しいです。

この記事が気に入ったらサポートをしてみませんか?