🎃

Next.jsの Incremental Static Regenerationを試してみた

2021/09/06に公開

Incremental Static Regeneration とは

Incremental Static Regeneration(ISR)はNext.jsのビルドパターンの内の1つです。
直訳すると"段階的な静的再生成"ですね。簡単に説明すると、

  • クライアント側のリクエストに対し静的にビルドされたページを返す
  • 有効期限を越えた後にアクセスがあった場合、バックグラウンドで静的ページを再生成する
  • 次回のアクセス時に、再生成されたページを表示する

という流れとなります。
俗に言うstale-while-revalidateというキャッシュ戦略をNext.js上で実現可能にしたものです。

実装方法+サンプル

URL:https://next-js-isr.vercel.app/

実装自体は非常にシンプルです。
下記のように、getStaticProps関数の返り値にrevalidateを追加することでISRが有効になります。

import type { GetStaticProps, NextPage } from 'next';
import Head from 'next/head';
import Image from 'next/image';
import styles from '../styles/Home.module.css';

type Props = {
   date: number;
};

export const getStaticProps: GetStaticProps<Props> = async () => {
   const date = Date.now();

   return {
       props: { date },
       revalidate: 10, // 更新間隔
   };
};

const Home: NextPage<Props> = ({ date }) => {
   return (
       <div className={styles.container}>
       // ~ 省略 ~
       
        <p>now:{date}</p>
        <p>静的に出力されたHTMLを10秒ごとに更新します</p>
        
       // ~ 省略 ~
       </div>
   );
};

export default Home;

課題

特定のホスティングサービスにロックインされる

ISRを利用可能なホスティングサービスは、VercelやAmplify等に限られています。
もし他のサービスに乗り換えたくなった場合、それがISRに対応している必要があります。

データと表示の整合性が取れない

常に最新のデータを表示しなければならない場合、ISRは不向きです。
(アクセス直後に古いデータが表示されることを許容するのであれば、マウント後に最新のデータを読み込み直すという手もあります。)

Fastly等のインスタント・パージで良くない?

それはそう。
すでにそちらで実装ずみであれば、わざわざISRを導入する必要はありません。
これからstale-while-revalidateのような仕組みを実装したいのであれば、

  • 実装が手軽
  • フロントエンドのみで完結する

という点がインスタント・パージと比較した際のISRのメリットとなりそうです。

Discussion