画像やCSS、JSファイルでF5の更新はもう不要?
キャッシュクリアをせずにパラメータで更新する方法
クライアントから仕事をいただき、テストアップなどをしてそれを確認してもらい、修正や微調整をして再確認をしてもらう時に、誰しも1度くらいは、「更新されてないんですけど…」「あ、それキャッシュですね」というやりとりを経験した事があるかと思います。
たまに今でもそういうやりとりをしている方を見る事もあるのですが、今ではこれは簡単に解決できる方法がありますし、逆にそれを知っていないとクライアントにも迷惑をかける事になるので、もし知らないという方はこれを機にぜひ覚えておきましょう。
環境などにもよりますが、自分では意識しなくとも全て自動化してしまう事も可能なため、この不要なキャッシュクリアしてください。といったやりとりや、ファイル名を一時的に変更してアップロードするなんて不毛な作業とはおさらばしましょう。
解決方法はパラメータを付ける
この解決方法はとても簡単で、パラメータを付けるだけで解決します。
画像にしろ、cssにしろ、jsファイルにしろ読み込むファイルの末尾にパラメータを付けるというだけです。
実際のパラメータの付け方やルールについて
実際にパラメータを付けるとなると、どんなパラメータ?となるものの、実際は決まりはなく、自分たちで管理しやすい、わかりやすいパラメータで問題ありません。
唯一決まっている点としては、「?
」を付けてパラメータを付けるという点です。?
の後は使える文字もいわゆる制作に使っている文字列などと変わりは無いのですが、使い勝手的な事を考えると、英数字とドットやアンダーバー、ハイフンくらいに留めておくのが良いかなとも感じます。
多くの場合、使われ方としては
- ver1.1 や ver_01などのバージョンを指定
- 20230101 などの日付を指定
- 001 などの数字で一時的に管理
といったようにバージョンや日付を指定して何かしら管理しやすい形で使われるか、一時的に今だけというパターンで、001など適当な値を入れて確認をしてもらうというような使い方をする事が多いかなと思います。
img(画像)の読込にパラメータを付けた場合
<!-- 通常の読み込み -->
<img src="/assets/img/picture.jpg">
<!-- パラメータを付けた読込 -->
<img src="/assets/img/picture.jpg?ver_01">
CSSの読込にパラメータを付けた場合
<!-- 通常の読み込み -->
<link rel="stylesheet" href="/assets/css/styles.css">
<!-- パラメータを付けた読込 -->
<link rel="stylesheet" href="/assets/css/styles.css?ver=1.1">
JSの読込にパラメータを付けた場合
<!-- 通常の読み込み -->
<script src="/assets/js/script.js">
<!-- パラメータを付けた読込 -->
<script src="/assets/js/script.js?20230101-1305">
といった具合に、?
の後にパラメータを付ければ問題ありません。
このパラメータを付けておけば、キャッシュをや、F5やCtrl+F5でというやりとりが不要になります。
余談:日付管理の際は時刻まで入れておくと良い
これよくやりがちですが、バージョンというほどバージョンで管理しないから、今日の日付でやっておこうという場合があり、?20230401
といったように、今の日付で一時的に付けたりする方がいますが、そうすると、その日に返信が返ってきて再修正が必要な時、ややこしくなります。
そうならないために、自分はいつも日付をやるなら時間までいれるようにして?202304011030
といったように、2023年4月1日10時30分更新という形にして、その後に再修正が入れば、1030を1300などの時刻変更でやるようにしています。
文字が長すぎてわかりにくいという場合は、?2023.0410.1530
といった形や、?2023-0410-1530
といったようにドットやハイフンも使えるためそのあたりを使って、自分ルールや社内ルールなど決めておくと良いのかもしれません。
完全に別ファイルとして読み込まれる
パラメータを付けたファイルというのは、元のファイルと別のファイルとして読み込まれることになります。
大本の根本となるファイルは同じファイル名の1ファイルではありますが、パラメータが付与されていると別のファイルとして再度読み込みを行うため、
- sample.jpg
- sample.jpg?202301011000
- sample.jpg?202301011005
といったようにすると、元は1つのファイルではありますが、全て別ファイルという扱いで読み込みを行うので、キャッシュが関係なく最新ファイルとして読み込みを行ってくれます。
実際に上記の様に、パラメータ無しとパラメータ付きでファイルを読み込みをし、画像やcssなどを更新してサイトにアクセスすると、パラメータ無しはキャッシュをみにいき、パラメータありは最新ファイルを読み込むというのが確認できます。(サーバー等の設定やキャッシュ状況などによるところもあります)
都度都度は面倒なので自動更新にする方法
クライアントとのやりとりで、キャッシュを~というのが無くなるのは良いのですが、更新する度にパラメータを更新してというのも、実際にはちょっと面倒という人もいるかもしれません。
1回や2回なら良いかもしれませんが、何度も更新→修正→更新→修正、、、というやりとりをすれば、その度にパラメータの変更をしていかなければなりません。
パラメータの更新を忘れてしまうと、結局更新前のファイルで更新されてませんが…?なんて言われる可能性もあるため、なんのためにこのパラメータを付けてやってるのかわからないという自体にもなってしまうため、注意も必要です。
だからこそ、限りなくミスが出ないようにそういった場合はある程度は自動でパラメータを入れられるようにしておく方が良いので、最後にその自動化について見ておきましょう。
出来るケースと出来ないケースがある
ただ自動化するしないは、誰でもどんなケースでもできるワケではありません。
特定のケースでのみできる、できないというのが出てきます。
厳密に言えば出来るのですが、やればやるだけ逆に無駄というかやらない方が良いという結果になるので、作っているサイトの形式など状況に合わせて対処していきましょう。
PHPやSSIが使えるなら自動化が可能
基本的に自動化が行えるパターンとしては、PHPが使えること、もしくはSSIが使えることというのが前提条件になっています。
そのため、PHPで作られている、もしくはHTMLで構築されているけれどPHPを使える設定にしているといったサイトやSSIを使える設定にしている場合に対処が可能です。
使い方は、読み込みのファイル名の後に、ファイルの更新日の日付のパラメータを自動的に挿入するようにすれば自動化が行えます。
PHPで自動化する場合
PHPで自動化する場合は下記のようなコードになります。
<!-- 使い方 -->
<link rel="stylesheet" href="CSSのパス?<?php echo filemtime('CSSのパス');?>">
<!-- 実際のサンプルコード -->
<link rel="stylesheet" href="/assets/css/style.css?<?php echo filemtime('./assets/css/style.css');?>">
filemtimeを使う事で、ファイルの更新時間を取得する事ができます。
そのためファイルの更新時間を取得して、それをパラメータをして表示することで、更新してアップロードすれば、その時刻が自動的にパラメータとして反映される事になります。
ただし相対パスのみ利用可能。絶対パスは不可
注意点としては、相対パスでの指定のみできるという点です。
ルートディレクトリを使った絶対パスも不可のため、相対パスで記入をするようにしましょう。
ファイルの読み込み時にはルートディレクトリからの絶対パスを使って読み込みは可能ですが、filemtimeを使って更新時刻を取得する際の読み込みは相対パスを使う必要があるため注意が必要です。
date()を使って見た目も整えるとわかりやすい
filemtimeを使う事で更新時刻を取得できますが、このデフォルト値だと取得するのがUnixタイムスタンプとなり、1970年1月1日午前0時0分0秒からどれだけ時間が過ぎたかという時刻の取得になってしまいます。
そのため実際にはdate関数を使って、私たち人間が見てわかりやすい更新時刻に変換して表示する方法を使うのが一般的でもありわかりやすく管理しやすくなります。
<link rel="stylesheet" href="/assets/css/style.css?<?php echo date('Ymdhm', filemtime('./assets/css/style.css'));?>">
これをしておけば、最初の設定だけで後は自分で毎回パラメータを付ける必要性もなく、更新時に自動的に付けてくれるのでミスも防げます。
SSIを使って自動化する方法
ランディングページなどのようにサイトではPHPを使えないという場合、SSIを使えるなら同じように自動化する事が出来ます。
<!-- 使い方-->
<script src="JSのパス?<!--#config timefmt='%Y%m%d%H%M' --><!--#flastmod file='JSのパス' -->"></script>
<!-- 実際のサンプルコード(相対パス)-->
<script src="/assets/js/script.js?<!--#config timefmt='%Y%m%d%H%M' --><!--#flastmod file='./assets/js/script.js' -->"></script>
<!-- 実際のサンプルコード(ルート絶対パス)-->
<script src="/assets/js/script.js?<!--#config timefmt='%Y%m%d%H%M' --><!--#flastmod virtual='/assets/js/script.js' -->"></script>
SSIもPHPと同様に、ファイルを読み込みした後、その最後に自動的にそのファイルの最終更新日時を自動的に取得してそれを表示するという設定になります。
読み込み方やパスに注意
少しPHPよりややこしい感じにはなりますが、SSIの場合は相対パスを使う場合、ルートディレクトリからの絶対パスを使う場合で少しコードが異なります。
相対パスで記載をする際には file を使います。
厳密に言うと、fileを使う場合は自分以下のディレクトリでしか使う事ができず、「../」といったような上の階層のファイルを読み込む事はできません。
そういった上の階層を読み込む場合はルートディレクトリからの絶対パスでもある virtual を使います。こちらであれば、ルートディレクトリからの絶対パスを指示すればどのファイルでも読み込むことができます。
そのため、個人的にはSSIを使う際にはこのvirtualを使う方がわかりやすくて使い勝手も良いかなとは思います。
PHPと同様にSSIでもこうしておくことで、ファイルを更新しアップロードすれば、自動的にパラメータも更新されるため、クライアントが確認する際には別ファイルを読み込むことでキャッシュに悩まされる事がなくなります。
どのファイルにパラメータを付けるかも要検討
パラメータを付ければキャッシュに悩まされる事もなくなるので良い事は良いのですが、とはいえこれを実践しようとすると、全てのソースコードで?のパラメータを付ける必要があり、現実的ではありませんし非常に見づらいコードになってしまいます。
そのため、更新頻度が高い部分にのみ基本は使いつつ、スポットで更新が入ったりする画像などに使うなどのような使い方がおすすめです。
- <head>で読み込むcssやjsファイル
- メインビジュアルなどの更新頻度の高い画像
このあたりはパラメータ付で予め作っておくというサイトも多いかもしれません。実際に色々なサイトを見ていると、<head>で読み込んでいる共通のcssやjsファイルで、更新をよくするようなファイルはパラメータを予め付けているというのも多いです。
逆に外部のjqueryのプラグインなどで使うjsファイルなどは更新頻度が高くないので付けずに行っているところが多いかなと思います。
あとは都度都度、画像の更新などが必要になった時などキャッシュでクライアントとのやりとりで面倒が発生しないため都度このパラメータをその時だけ付けて使うというやり方が多いのではないかなと感じますし、実際に自分もそういう使い方が多いです。
このパラメータを上手く使う事ができれば、クライアントとの確認などで無駄な工数や手間も減って、クライアントからもあの人との仕事だとそういうキャッシュだとか言われないといったメリットもあるので、ぜひ使い方は覚えておきましょう。
まとめ
制作案件のあるあるの1つにキャッシュ問題があるかと思います。
更新したのにクライアントのPCなどでの確認時にはキャッシュがクリアされていない…。
PCだとCtrl+F5などの更新で見る事ができますが、スマホだとなかなか難しいケースもあり、わざわざ画像やcssを別のファイル名に変換してHTMLのコードも修正し直してそれぞれをアップロードして確認してもらって…なんて事をしていた方も多いかもしれません。
今回のパラメータを付けて確認する方法であれば、半強制的に新しいファイルを読み込みできるかたちになりますので、そういったキャッシュのやりとりを無くす事ができてとても便利です。
実際、楽天のRMSなどを使っている方は楽天は特にキャッシュなどが非常に強く下手すると更新しても1日近くは旧ファイルを読み込んだりするので、このパラメータ付の呼び出し方を知っていれば対処する事ができるようにもなります。
自動更新は少し手間で難しく環境にも左右されますが、通常のやり方は慣れればとても簡単ですし、実際の現場でもかなり助かるケースもありますので、これを機にしっかりと身に付けておきましょう。
記事のシェアにご協力お願いします