前回のエントリ(ブラウザのキャッシュコントロールを正しく理解する)でブラウザ側のキャッシュ制御について説明しました。
ただ動的スクリプトなら、次の例のようにHTTPレスポンスヘッダを操作すればいいのですが、
<?php
header('Content-Type: text/plain; charset=UTF-8');
header('Cache-Control: max-age=0');
echo "Hello World!";
?>
スクリプトを介さない静的リソース(HTMLファイル、JSファイル、CSSファイル、画像ファイルなど)はどうやってHTTPレスポンスを操作すればいいかというと、もしApacheを利用している場合は mod_header と mod_rewrite を利用して次のように簡単に出来ます!
設定例
想定ケースとして、次のようにブラウザ側のキャッシュを制御したいと仮定します。
(表の下にいくほど、キャッシュの強度が高い=サーバ側へのアクセス回数や通信量を抑えられる)
対象 | 期待する挙動 |
---|---|
PHPスクリプト | ブラウザにキャッシュされず毎回アクセスして欲しい。動的コンテンツなのでサーバから304レスポンスを返すこともない。 |
HTMLファイル | コンテンツに文言ミスがあった場合に、修正を即座に反映したい。ただサイズが大きいので、普段に変更がない場合はコンテンツ内容をレスポンスしたくない(304レスポンス) |
CSSファイル、JSファイル | 何かアプリケーションに不具合があった場合に修正を反映したいが、最悪10分間は許容できる。サイズが大きいので普段に変更がない場合はコンテンツ内容をレスポンスしたくない(304レスポンス) |
画像ファイル | 運用でめったに更新しない。修正した場合も反映まで1日は許容できる。サイズが大きいので普段に変更がない場合はコンテンツ内容をレスポンスしたくない(304レスポンス) |
この要件を満たすには、次のように .htaccess
へ記載します。
RewriteEngine on
RewriteRule \.php$ - [L,E=X_CACHE_PATTERN1:]
RewriteRule \.html$ - [L,E=X_CACHE_PATTERN2:]
RewriteRule \.(css|js)$ - [L,E=X_CACHE_PATTERN3:]
RewriteRule \.(gif|jpe?g|png)$ - [L,E=X_CACHE_PATTERN4:]
# For dynamic contents
Header set Cache-Control "no-cache" env=X_CACHE_PATTERN1
Header unset Expires env=X_CACHE_PATTERN1
Header unset Last-Modified env=X_CACHE_PATTERN1
Header unset Etag env=X_CACHE_PATTERN1
# For HTML files
Header set Cache-Control "max-age=0" env=X_CACHE_PATTERN2
Header set Expires "Mon, 26 Jul 1997 05:00:00 GMT" env=X_CACHE_PATTERN2
# For CSS,JavaScript files
Header set Cache-Control "max-age=600" env=X_CACHE_PATTERN3
# For Image files
Header set Cache-Control "max-age=86400" env=X_CACHE_PATTERN4
ファイルの拡張子を元に、キャッシュのパターンを4通り設定しています。
(テンポラリ的にApache環境変数を利用。)
《拡張子が .php
の場合》
HTTPレスポンスヘッダ Cache-Control: no-cache
をセットし、Expires
Last-Modified
Etag
は念のため削除しています(なんとなく気持ち悪いので)。
《拡張子が .html
の場合》
Cache-Control
と Expires
で、即に期限切れにしています。Last-Modified
Etag
はApacheで自動的に付与されます(特殊な設定変更をしていなければ)。
《拡張子が .css
または .js
の場合》
Cache-Control: max-age=600
で600秒(10分間)のキャッシュを指定しています。こちらもLast-Modified
Etag
はApacheで自動的に付与されます。
本当はExpires
も設定したいところですが .htaccess
で時間計算や文字列生成ができないので^^; ただ大抵のブラウザは、Cache-Control
だけで十分かと思います。
《拡張子が画像系ファイルの場合》
CSSやJSの時よりキャッシュ期間を長く(max-age=86400:1日)しています。
おわりに
静的リソースのブラウザキャッシュを制御することによって、ユーザのブラウザ描写待ち時間も減るとともに、サーバの負荷やネットワーク通信量を抑えられます。
とくに大きい画像がある場合はキャッシュは効果が高いので、適切に設定しましょう!