Webサイトの更新が先方のブラウザで反映されない!そんな時は

この記事は2024/08/01に作成されました。
Webサイト上のCSSファイルや画像ファイルを更新し、他の人に確認をお願いしたのに、自分以外の環境では反映されず、古いまま表示されてしまう…そんな経験はないでしょうか。
「キャッシュのせい」「スーパーリロードで直る」という事自体はなんとなく把握しているかと思いますが、ここでは一旦キャッシュとは一体なんなのか、そしてなぜスーパーリロードで直るのか、改めて確認してみましょう。
なぜ前のデータのままとなるのか?
これはブラウザ上に「キャッシュ」が残るからです。キャッシュとは、ブラウザがページの表示を高速に行う、一度取得したリソース(つまりCSSファイルや画像ファイルなど)を保存しておく…という仕組みです。
たとえば、ユーザーがとあるWebページにアクセスしたとき、そのページのCSSファイルや画像ファイルなどのリソースを一度ブラウザにダウンロードします。これを「キャッシュ」と呼びます。これにより、次に同じページにアクセスする際、このキャッシュによって、次に同じページにアクセスする際、これらのリソースがブラウザに保存されているデータから読み込まれるため、再度データを取得することなく、ページを素早く表示することができます。
本来であればこのように便利な機能なのですが、CSSデータや画像データの更新をしてもブラウザに保存されている以前のデータを読み込もうとしてしまう、という現象が発生してしまいます。これが更新しても反映されない、という現象の正体です。

新しいデータを反映させるには
このようなキャッシュによる「更新が反映されない」という問題に対処するためには、いくつかの方法があります。一番簡単な手法としては、「スーパーリロードを行う」ことです。通常のリロード(更新ボタン、F5キーなど)ではキャッシュを利用するために古いファイルのままとなってしまうのですが、スーパーリロードは「ブラウザのキャッシュを使用せず、再度サーバー上からデータを読み込み直すリロード」を行うため、新しいデータでサイトを閲覧することができます。
スーパーリロードの方法としては、WindowsであればCtrl + Shift + RやShift+ブラウザの更新ボタン、MacであればCmd + Shift + Rなどで行う事ができます。
しかしこの方法には問題があり、「確認してもらう人に手間を掛けさせてしまうこと」、「スマートフォンだと履歴ごと削除しなければいけないので使い辛い」という点があります。
また、リバースプロキシやプロキシサーバーを中継して表示を行っているサイトや、CDNを使って表示の高速化を行っているサイトでは、サーバー側でキャッシュが保持され続けることがあるため、ブラウザ上でキャッシュを削除しても古いデータが表示されたままになることがあります。
そのため、基本的にはサイトの管理者が後述の手段を取る事が推奨されます。
クエリパラメータを使用しよう
CSSやJavaScriptなどのリソースファイルのURLにクエリパラメータを追加する方法がもっとも簡単で効果的かと思います。例えば、style.cssというファイルを使用している場合、通常は次のように読み込みのコードを記述しているかと思います。
<link rel="stylesheet" href="/style.css">このようなCSS読み込みをしているサイトに「2回」アクセスしたとき、どうなるかを考えてみましょう。
1回目のアクセスでstyle.cssをブラウザが読み込み、ブラウザにキャッシュとして保存されます。
2回目のアクセス時には、style.cssのキャッシュが存在するので、新たに読み込むことはなく、キャッシュから呼び出して表示します。
この時、1回目の2回目の間にstyle.cssが更新されていても、ファイル名が同じファイルであればブラウザ側は「同じもの」と判断してしまうため、わざわざ再ロードを行うことなくキャッシュから読み込んでしまいます。
これを防ぐために、ファイルを更新した時は以下のように「クエリパラメータ」を付けて記述しましょう。
<link rel="stylesheet" href="/style.css?ver2"> このように記述することで、ブラウザはこれを「新しいファイル」として認識し、結果としてキャッシュではなく最新のファイルをダウンロードをするようになります。
この?ver2という部分にどういう意味があるかと言われると、実際特に意味はありません。本来であればこのようなクエリパラメータは…例えば、なにかサーバー側にデータを渡すときなどに使いますが、cssでそういったものを読み込むことはないので、本当に「別のファイルとして認識させる」ためだけに使用しています。
上記の例では?ver2としましたが、この部分は前と違うものであれば何でも構いません。更新するたびにバージョンを更新していく、更新日付にするなど管理しやすい値を与えるといいでしょう。
ヘッダーでの制御
HTTPヘッダーに「Cache-Control」という値を設定することでユーザーのブラウザのキャッシュを制御することができます。
例えばCache-Control: no-store と設定すると一切のキャッシュを許さない形となり、毎回データをロードする形となります。これは一見便利そうですが、一切のキャッシュを許さない = 読み込みが遅くなる、ということなので使うには注意が必要です。
一例として、Cache-Controlで使用できる値は以下のようなものがあります。
| 設定 | 説明 |
max-age=秒数 | 指定した秒数が過ぎるまではキャッシュを利用する。例として、360と指定した場合は6分以内の再アクセスであればキャッシュを使用する。なお、これら設定含めキャッシュの設定はブラウザ側が判断するため、必ずしも指定した通りにはならない。 |
no-cache | キャッシュを使用する前にサーバーに問い合わせてデータの更新確認を行う。 |
no-store | キャッシュを一切行わないようにする。 |
public | すべてのキャッシュが保存可能という事を明示する(ほぼデフォルトの処理) |
must-revalidate | max-ageと組み合わせて使う。期限切れの場合は使用しないように明示する。 |
immutable | このサイトではCSSなどの更新がほとんど行われない、という事を明示する。max-ageと組み合わせて使う。キャッシュが期限切れになっていない限りキャッシュされたデータを使用する。 |
他にもE-Tag(ファイルを比較するための識別子)やLast-Modified(最終更新日)といった情報がヘッダーで使用されることもあります。これらが原因で、ブラウザがキャッシュを保持し続ける場合があるため、更新が反映されないときはこれらの値が正しく送信されているか、なども確認してください。
やり方としては以上のどれかになるかと思いますが、基本的にはクエリパラメータを利用した方法が一番わかりやすいかと思います。
プログラマー / S.Y
PHPフレームワーク「CodeIgniter」を用いたWebサイト開発を専門とする。要件に応じ、WordPressサイトの構築から、JavaScriptを活用した動的なフロントエンド・バックエンドの実装まで、幅広く担当する。


