Stale While Revalidate

最近フロントエンド開発のデータfetchの際よく見かける、SWRについて、実際に試して見ました。

https://swr.vercel.app/ja
上記より引用

“SWR” という名前は、 HTTP RFC 5861(opens in a new tab) で提唱された HTTP キャッシュ無効化戦略である stale-while-revalidate に由来しています。 SWR は、まずキャッシュからデータを返し(stale)、次にフェッチリクエストを送り(revalidate)、最後に最新のデータを持ってくるという戦略です。

上記「まずキャッシュからデータを返し」という部分が重要です。その後fetchしキャッシュを最新にします。
これを実現するためには、サーバのレスポンスヘッダCache-Controlにstale-while-revalidateを追加する必要があります。

参考
https://blog.jxck.io/entries/2016-04-16/stale-while-revalidate.html#web-%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5

https://nextjs.org/docs/app/building-your-application/caching#time-based-revalidation

下記は、stale-while-revalidateのタイムアウト時、リクエストの結果、ブラウザに表示された時間と、実際にサーバから返された時間が違っていることを示しています。キャッシュからまずデータが返され、その後サーバにfetchしにいっていることが確認できます。

環境) Mac(arm64)

sudo tcpdump -i lo0 port 8000 -n -A

下記テストに使ったコードです。
サーバはpython fastapi、クライアントは、next.js app router / typescript (layout.tsxは省略)

main.py

起動

uvicorn main:app –reload

page.tsx

起動

npm run dev

stale-while-revalidateを削除したり max-age、revalidateの値を変えたりして、実際に動かしてみると理解が深まります。