ApacheでCache-Controlを設定し、再訪問時の高速化を図る
jsや画像といった変更頻度が高くないファイルはブラウザにキャッシュして、次からサーバに問い合わせることなく使用できればWebサイトの高速化につながる。
キャッシュを使う用指示するには、サーバからCache-Controlのmax-age
を指定して返せれば良い。この設定はApacheではmod_expires
モジュールをロードして行う。
mod_expiresの文書を参考にしてApacheに設定する。
mod_expires 実際の設定
文書にはExpires HTTP ヘッダ と Cache-Control ヘッダの max-age ディレクティブの 設定を制御します
、とあり、後方互換のためのExpiresヘッダと主流のCache-Controlヘッダの両方を付与するモジュールのようである。
ドキュメントに従い次のように設定。画像ファイルとjsファイルは稀にしか変更が入らないファイルであるため確実に設定しておく。
ユーザの最終アクセスから30日間はファイルを取り直さない設定をおこなった。もしファイルを更新したい場合はファイル名を変更して、それをhtmlファイルから指せば良い。
ファイルの更新を反映させるために敢えて更新の度にファイル名を変更する技はCache Busting
と呼ばれ、WebPackを使っていたら自動で行ってくれるし、Gulpでもgulp-revとgulp-rev-replaceを使用することで達成できる。
JS、CSS、画像ファイルといった静的ファイルにリビジョンを付与してブラウザのキャッシュ問題を回避するなども参考になる。
例えば次のようなハッシュを自動でつけてくれる。
lib/combined-c04a66ba14.min.js
さて、話をApacheの設定に戻す。
/etc/httpd/conf.modules.d/00-base.conf
にて
LoadModule expires_module modules/mod_expires.so
と既に必要なモジュールがロードされていたため下記をVirtualHost内に書き込めばうまくいくはずである。
ExpiresActive On
ExpiresDefault "access plus 0 hours"
ExpiresByType image/jpeg "access plus 30 days"
ExpiresByType image/png "access plus 30 days"
ExpiresByType image/webp "access plus 30 days"
ExpiresByType application/javascript "access plus 30 days"
これで設定完了である。htmlファイルは変更したらすぐに反映させたいためCache-Controlの効果が0秒で切れるようにしている。
mod_expiresの設定反映を確認
jsファイルにアクセスした時のResponse HeaderのBefore/Afterを確認する。
Before:
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 22240
Content-Type: application/javascript
Date: Sun, 16 Aug 2020 17:06:04 GMT
Keep-Alive: timeout=5, max=98
Last-Modified: Sun, 16 Aug 2020 16:11:09 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips
Vary: Accept-Encoding
After:
Accept-Ranges: bytes
Cache-Control: max-age=2592000
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 22240
Content-Type: application/javascript
Date: Sun, 16 Aug 2020 16:29:30 GMT
Expires: Tue, 15 Sep 2020 16:29:30 GMT
Keep-Alive: timeout=5, max=98
Last-Modified: Sun, 16 Aug 2020 16:11:09 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips
Vary: Accept-Encoding
ExpiresとCache-Controlが付与されたのが分かるだろう。
ちなみにExpiresは古い形式で、サーバの後方互換性を保つために加えられているものである。基本的にはCache-Controlだけで十分かとは思う。