はじめに
HTTPヘッダーのCache-Controlには色々パラメーターがあり、どうやって指定するのか?
この記事でまとめます。
キャッシュの種類
Private キャッシュ VS Shared キャッシュ
キャッシュには様々の種類がありますが、大まかにPrivate キャッシュとShared キャッシュに分類できます。
Private キャッシュ
単独のユーザーに利用されるキャッシュ。基本はユーザー使用されるブラウザー側で保持します。
一度ブラウザーキャッシュに保存される内容は、再び訪問(リクエスト)する際、サーバーに再度アクセス必要がなくなります。これである程度サーバーへの負荷を分散できるでしょう。
Cache-Controlヘッダーに関連のパラメーター:private
主な利用シナリオ:ウェブページの戻る/進む操作
Shared キャシュ
名前の通り、複数ユーザがシェアできるためのレスポンスを保存するキャッシュ。主にプロクシーサーバーで保持します。
Cache-Controlヘッダーに関連のパラメーター:public
主な利用シナリオ:ホットリソースを再利用して、ネットワークのトラフィックやオリジナルサーバーへの負荷を減らす
※ 上記ブラウザーキャッシュとプロクシーキャッシュ以外に、ゲートウェイ、CDN、ロードバランサーキャッシュもございます。
Cache-Control ヘッダー主なパラメータ
no-store
キャッシュの中、クライアントのリクエストとサーバーのレスポンスについての内容何も保存しません。毎回必ずオリジナルサーバーにアクセスして、レスポンスをとります。
no-cache
キャッシュした内容を渡す前に、オリジナルサーバーに検証します(キャッシュは未だ有効するかどうかを)。
max-age
max-ageというパラメータはキャッシュの有効期限と関われます。デフォルト単位は秒です。
キャッシュの更新:オリジナルサーバー側のリソースが更新した場合、キャッシュも更新すべきです。HTTPのクライアントサーバープロトコルより、リソースを変更した時にサーバーがキャッシュやクライアントに連絡しませんので。サーバーは、リソースの有効期限を伝えなければなりません。
「リソースが陳腐化していないと考えられる最長期間を表す。。。変更しない予定のアプリケーションのファイルには、たいてい積極的なキャッシュを行います。これは例えば画像、CSS ファイル、JavaScript ファイルといった静的なファイルが含まれます」
max-ageを100に設定した場合は以下の図解の通り、
- Client 1はリクエストする時、未だキャッシュがないため、オリジナルサーバーからのレスポンスはキャッシュに保存され、レスポンスします。
- Client 2は10秒後リクエストする時、キャッシュが未だfreshのため、オリジナルサーバーにアクセスせず、キャッシュからレスポンス内容を取ります。
- Client 3は100秒後リクエストする時、キャッシュがはstale(陳腐化)になったため、 If-None-Match (またはIf-Modified-Since)を付加してリクエストをオリジナルサーバーに転送します。もしキャッシュは新鮮であれば、サーバーは 304 (Not Modified) ヘッダーを返します。要求されたリソースはキャッシュより送信するため、オリジナルサーバー→キャッシュ間の帯域を節約します。
では、これらのパラメータどう設定しますか?
次のフロー図をご参考ください。
最適な Cache-Control ポリシーの定義
出所:Google Developers - Web Fundamentals, HTTP Cache
具体例
リソースベースのセッティングの考え方を見ていきましょう。
開発用のリソースファイルのHTML、JS、CSS、ImagesなどのCache-Control設定例とその理由:
HTML
設定:private, no-cache
意味:単独のユーザーのみに利用され、キャッシュした内容を渡す前に、オリジナルサーバーに検証します。
理由:アプリのプライマリーリソースとして、毎回リクエストの時サーバーに検証する必要があります。
JS, CSS, Images
設定:public, max-age=31536000
意味:複数ユーザー利用でき、有効期限は1年間
理由:JS, CSS, Imagesというような静的なファイルはほぼ変更しませんので、直接キャッシュから読み込んでも構いません。
###参考
[1] MDN - HTTP caching
[2] Google Web Fundamentals - [HTTP Cache] (https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching)
[3] Google Chrome Developersチャネル - Caching Headers