200stackの設計をする際に、なるべくキャッシュからレスポンスするけど、なるべく早く変更を反映することにこだわろうと考えました。せっかく静的サイトにするので動的だと難しいレベルのレスポンス速度にしたいけど、キャッシュの時間を伸ばしすぎると、ページの更新がサイトに反映されるまでに時間がかかるため、どのようにバランスを取るかが重要でした。
このバランスを取る仕様として、下記のように設計しました。
HTMLなどのドキュメントのキャッシュ仕様
キャッシュと更新の流れ
- リクエスト時にキャッシュがなければレスポンスをキャッシュに保存してレスポンス。
- 30秒間は無条件でキャッシュをレスポンス。
- 31秒〜30分の間にリクエストを受けたら、キャッシュを即時レスポンスしつつバックグラウンドでドキュメントのファイルが更新されていないかを確認。
- 更新されている場合は、キャッシュを更新する。
- キャッシュされてから30分間リクエストがない場合はキャッシュを削除して最初の状態に戻る。
ドキュメントは更新する可能性が高いので、SWR(stale-while-revalidate)パターンを参考に、キャッシュを返しつつバックグラウンドで更新確認を行う仕様にしました。
SWRはリクエストを受けた際、キャッシュがある場合は即レスポンスをしつつ、バックグラウンドでオリジンが更新していないかを確認し更新されている場合はキャッシュを更新する仕組みです。ユーザーは毎回キャッシュからレスポンスを受け取れるため待ち時間が短縮されます。
Cache-Controlヘッダーには public, max-age=0, s-maxage=1800, stale-while-revalidate=1800, must-revalidate, no-transform を設定しています。
ブラウザには極力キャッシュさせないために max-age=0 と must-revalidate を設定しています。s-maxage=1800 を設定しているので、最大30分はCDNでキャッシュを保存しますが、キャッシュ期間内でも30秒を超えるとバックグラウンドでオリジンが更新されていないかを確認し、更新されていた場合はオリジンのファイルを取得しキャッシュを更新します。
JSやCSS・画像などのドキュメント以外のキャッシュ仕様
- 無条件で1年間キャッシュする
- ヘッダに immutable を設定してブラウザにキャッシュさせる
JSやCSS・画像は、フレームワークでCache Bustingの機能を使う前提にしました。ファイルが更新される際は、ビルド時にファイル名がハッシュ付きで変わるため、キャッシュの更新を考える必要がなくなり、いつでも高速でレスポンスすることができます。
200stackならこの仕様で配信できます
200stackで配信した場合は、このキャッシュ仕様になっているので、更新とキャッシュのバランスがとれた状態で配信できます。より良い仕様や問題があれば是非ご連絡ください!