Remix on Vercelでstale-while-revalidateを試してみた

Remix公式のTwitterでVercelでデプロイすればstale-while-revalidateがすぐに利用できるよーとコメントがあったので早速試してみました。
2021.12.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、CX事業本部MAD事業部の森茂です。
今回はRemixの小ネタを紹介させていただきます。

Remix公式のTwitterでVercelでデプロイすればstale-while-revalidate(SWR)がすぐに利用できるよーとコメントがあったので早速試してみました。

Vercel supports stale-while-revalidate so you can speed that puppy up for everybody!

▲ + ? = ❤️

Stale-While-Revalidate(SWR)

Next.jsのISR(Incremental Static Regeneration)が話題になったことでStale-While-Revalidateについても改めて耳にすることが増えてきました。少々乱暴に言葉をまとめるとキャッシュ戦略のひとつとなります。

例えば今回Remixのサンプルにあるheaderの下記情報を付与した場合、

'Cache-Control': 'max-age=0, s-maxage=300, stale-while-revalidate=300'
  • max-age -> クライアントのブラウザにはキャッシュをさせない
  • s-maxage -> Vercel上での300秒キャッシュ時間(Vercelの公式ドキュメントではベストエフォートとのこと)
  • stale-while-revalidate -> 生成後300秒間はキャッシュを返す。300秒経過後にキャッシュにアクセスがあった場合、そのアクセスに対してはキャッシュを返し、バックグラウンドでは新規キャッシュの生成を行う。生成完了後からは新規のキャシュを返す。

といった動作になり、ユーザーに返すキャッシュをある程度コントロールすることができるようになります。

やってみた

SWRの動作を検証するためにキャッシュ時間を30秒に設定し、サーバーサイドでの実行日時とクライアントサイドでの実行日時を出力するページを作成してVercelにデプロイします。

Vercelへのデプロイについては下記の記事を参照ください。

routes/index.tsx

import { HeadersFunction, LoaderFunction, useLoaderData } from 'remix';

export const headers: HeadersFunction = () => {
  return {
    'Cache-Control': 'max-age=0, s-maxage=30, stale-while-revalidate=30',
  };
};

export const loader: LoaderFunction = () => {
  return new Date().toUTCString();
};

export default function Index() {
  const data = useLoaderData<string>();

  return (
    <div className="p-8">
      <h1>swr</h1>
      <p>{data}</p>
      <h1>csr</h1>
      <p>{new Date().toUTCString()}</p>
    </div>
  );
}

動作確認

デプロイ後にアクセスしてヘッダー情報を確認してみます。x-vercel-cacheMISSを返しており、サーバーサイドの日時とクライアントサイドの日時も同じタイミングになっています。

つづけてページを更新すると、x-vercel-cacheHITを返し、サーバーサイドの日時は先程のまま、クライアントサイドの日時のみ変更されました。

30秒を超過して再度ページを更新すると、x-vercel-cacheSTALEを返し、サーバーサイドの日時は先程のまま、クライアントサイドの日時のみ変更されています。この時点ではクライアントにはキャッシュを返していますがバックグラウンドではキャッシュが再生成されています。

再びページを更新すると、x-vercel-cacheHITを返し、サーバーサイドの日時がSTALEを返した日時に変更されました。

出力結果に対して強い整合性が求められるコンテンツには不向きですが、動的な情報を扱う場合にもページ自体のキャッシュを活かしたい場合には有用な手段になると思います。

さいごに

RemixとVercelを利用して気軽にSWRを利用することができました。
ぜひみなさんもRemixでNext.jsとはまた違う開発体験を楽しんでみてください?