CSSや画像といった静的リソースはブラウザのキャッシュによって保存され、ページを読み込むたびに静的リソースを毎回サーバーから読み込む必要を無くすweb制作では欠かせない技術の一つです。
ですが、このキャッシュに苦しめられることもまたweb制作の現場ではよくあることです。
目次
キャッシュの罠
web制作の現場ではサイトを制作する過程で、クライアントや上司に変更箇所を確認してもらうことが多くあります。
そこでよくあるのが、
ぼく「ページの画像を変更したのでチェックお願いします」
担当者「んーまだ変わってないみたいですねぇ」
ぼく「失礼いたしました。ただいま画像を差し替えました」
担当者「んーまだ変わってないみたいですねぇ」
サーバーを何回か確認したぼく「…失礼いたしました。ただいま画像を差し替えました」
担当者「んーまだ変わってないみたいですねぇ」
ぼく「」
こういうときは大抵キャッシュが残っているためにページ読み込みで古いファイルが読み込まれてしまっているために起こる問題です。
キャッシュを消してくれと言うにも普段web制作に関わらない人からしたらキャッシュの消し方なんか知らないし、そのやりとりを何度もやり取りするのは非常に非効率です。
そこで、ファイルを更新したら勝手にキャッシュを破棄させる仕組みを作れないかと思ったわけなのです。
キャッシュを破棄して読み込む方法
まず、ブラウザキャッシュを破棄して静的リソースを読み込ませる方法として最も手っ取り早いのが、リソースにパラメータを付ける方法です。
// 基本的な記述方法 // HTML <link href="./css/style.css?v202106" rel="stylesheet" type="text/css"> <img src="./images/example.png?v202106" alt="example">
imgタグ等のファイル名の後ろに?〇〇
を付ける方法。よくある記述だとバージョンを表すvをつけて?v1_0
とか、日付を付ける?20210101
とかがあります。
HTMLでは該当のリソースを更新するたびにソースのパラメータを更新する必要があるためなかなかの負担です。
そのため、PHPを利用して動的にパラメータを変更するのが現実的です。WordPressもPHPで作られているので使用できる場所は多いと思います。
<?php // タイムスタンプ $now = time(); // 現在日時をフォーマット指定して $now = date('YmdHis'); ?> <link href="/css/style.css?<?php echo $now; ?>" rel="stylesheet" type="text/css">
上記のコードにもあるように、動的に出力する際は日付を出力することがほとんどです。
自動でキャッシュが破棄されるので便利に見えますがここにも問題はあります。
キャッシュされなさすぎ問題
本来は読み込みを早くして快適にブラウジングするためにあるキャッシュを消してしまうので、ユーザビリティとしては問題があります。
解決法としては、date()関数で取得する日付を「○年○月○日○時○分○秒」から「○年○月○日」といったように詳細度を下げる方法や、制作物のリリースまでは詳細度を上げてリリースしたら詳細度を下げるといったものがあります。
ですがリリース後にも修正はありますし、リリースしたあとはなるべくキャッシュを破棄することは避けたいです。そこで本題ですが、サーバーにあるリソースが更新されたらそのリソースだけ更新できるようにしたいと思ったわけです。
ファイルを更新したときだけキャッシュを破棄させる方法
なんとPHPにはファイルを更新した日時が取得できるfilemtime()
という関数が存在しているということで、パラメータにその値を付与すれば更新したリソースだけキャッシュが破棄されるという寸法です。
// 静的サイト <?php echo date("ymdHis",filemtime( "./style.css")); ?> // wordpress <?php echo date("ymdHis",filemtime( get_template_directory()."/style.css")); ?>
引用:【php】filemtime()を使ってファイルの更新日を取得する
上記コードでdate()フォーマットを指定してパラメータを付与することが出来ます。
<link rel="stylesheet" href="./style.css?<?php echo date("ymdHis",filemtime( "./style.css")); ?>" />
これで必要な箇所だけ変更のたびにキャッシュを破棄することができるようになりました。めでたしめでたし。
まとめ
この「キャッシュを消してください戦争」に終止符を付けるためにも先人に習って今回の記事を書かさせていただきました。
すでに解決していることを改めて記事にするのはどうかと思いましたが、少しでも世のwe制作者が苦しみから開放されることを祈って…