CSS・JavaScriptを強制更新【HTMLキャッシュバスティング】

キャッシュを削除してもらえますか。

というお願いは心苦しいものです。

CSSを更新したはいいけど、毎回「変わってないんですけど」とクレーム…。

CSSを修正するたびにファイル名を変更するのも面倒くさい…。

ブラウザキャッシュを強制的に更新する方法はないの?

この問題はキャッシュバスティング(CacheBusting)で解決します。

しかもこの方法なら、CSS・JSファイルの名前を変更するような面倒もありません。

画像ファイルを強制的に更新させるHTMLキャッシュバスティングにも応用できます。

この記事では、HTMLにキャッシュバスティングを仕込んで、CSS・JavaScriptを強制的に更新させる方法を解説します。

キャッシュバスティングの仕組み

htmlのキャッシュバスティングを説明する画像

キャッシュバスティングの仕組みは単純です。

  1. 閲覧者がページにアクセスすると、ブラウザがページ読込みをリクエストします。
  2. サーバーのHTMLには、キャッシュバスティングのスクリプトを埋め込んでおきます。このスクリプトは、<link>タグ(CSS・JSファイル名にクエリを付けたもの)を出力します。
  3. その結果、ブラウザはHTMLの<link>タグとキャッシュを「別物」と誤認し、既存のキャッシュが無いものと判断します。
  4. そうなると、リクエストのたびに、ブラウザはサーバーのCSS・JSファイルを新規に読み込みするしかなくなるわけです。

ブラウザがHTMLをレンダリングするタイミングで、強制的にブラウザキャッシュを更新する挙動になります。

これがキャッシュバスティングの仕組みです。

WordPressのキャッシュバスティングについては、次の記事で解説しています。

キャッシュバスティングでCSSを更新する方法

<!DOCTYPE html>
<html>
<head> 
 
<script>
  document.write(
    '<link rel="stylesheet" href="CSSファイル名.css?' + new Date().getTime() + '">'
  );
</script>
</head>
<body>
</body>
</html>

“new Date().getTime()”の部分で時間を取得します。

上の赤字部分のスクリプトをHTMLに埋め込みます。

埋め込む位置は、</head>(閉じ)タグの直前にしておきます。

スクリプトを埋め込んだらブラウザでページを更新し、開発モード(F12)でHTMLソースを見てみると…

CSSファイルをキャッシュバスティングCacheBustingするコードを出力した様子を示す画像

水色ハイライト部分に、CSSファイルのリンクがクエリ付きで出力されていることが確認できます。

これで、リンク(href=”ファイル.css?毎回異なるクエリ“)が、キャッシュ.cssを「別物」と誤認します。

その結果、閲覧者がページを訪問・更新する度にCSSファイルが強制的に更新されることになります。

キャッシュバスティングでJavaScriptを更新する方法

<!DOCTYPE html>
<html>
<head>
</head>
<body>

<script>
  document.write(
    '<script src="JavaScriptファイル名.js?' + new Date().getTime() + '"><\/script>'
  );
</script>
</body>
</html>

<script>~<\/script>のスクリプトをHTMLに埋め込みます。(<\/script>の「\/」部分は誤記ではありません。このままコピーして大丈夫です。)

埋め込む位置は、</body>(閉じ)タグの直前にしておきます。

スクリプトを埋め込んだらブラウザでページを更新し、開発モード(F12)でHTMLソースを見てみると…

JavaScriptファイルをキャッシュバスティングCacheBustingするコードを出力した様子を示す画像

水色ハイライト部分に、JSファイルのリンクがクエリ付きで出力されていることが確認できます。

これで、リンク(src=”ファイル.js?毎回異なるクエリ“)が、キャッシュ.jsを「別物」と誤認します。

その結果、閲覧者がページを訪問・更新する度にJSファイルが強制的に更新されることになります。

キャッシュバスティングしていることを隠す方法

HTMLに埋め込んだキャッシュバスティングのスクリプトは、ブラウザの開発モードで見えてしまいます。

それが嫌な場合は…CSSやJSファイルを呼び出すためのJavaScriptを作って、HTMLでその.jsファイル(例えばcachebusting.js)を読み込むようにします。

// cachebusting.js
// </head>タグ直前にCSSを読み込むタグを出力
(function() {
   var elem  = document.createElement('link');
   elem.setAttribute('rel', 'stylesheet');
   elem.setAttribute('href', 'CSSファイル名.css?' + new Date().getTime());
   document.getElementsByTagName('head')[0].appendChild(elem);
 })();

// </body>タグ直前にJavaScriptを読み込むタグを出力
(function() {
  var elem = document.createElement('script');
  elem.setAttribute('src', 'JavaScriptファイル名.js?' + new Date().getTime());
  document.getElementsByTagName('body')[0].appendChild(elem);
})();

上のcachebusting.jsを読み込みするスクリプトをHTMLに埋め込みます。

埋め込む位置は、HTMLのレンダリングを最優先させるために、</body>(閉じ)タグの直前にしておきます。

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="cachebusting.js" charset="utf-8"></script></body>
</html>

Uncaught TypeError

エラー「Uncaught TypeError」が返ってくる場合は、cachebusting.jsを読み込みするスクリプトの実行に失敗しています。

エラーの原因は、HTMLが上から順にレンダリングされていくなかで、スクリプト”document.getElementsByTagName(‘body’)”が<body>タグの出現前に実行されてしまったからです。

スクリプトをHTMLの<head>タグ内に埋め込んでいないか確認してください。

スクリプトをgetElementsByTagName(‘body’)とした場合は、<body>タグ内にスクリプトを埋め込む必要があります。

まとめ

  • キャッシュバスティングは、ファイル名に毎回異なるクエリを付けてキャッシュを「別物」と誤認させる仕組み
  • CSS・JSファイルだけじゃなく、画像ファイルのキャッシュバスティングにも応用できる
  • キャッシュバスティングしていることを隠すには、さらにキャッシュバスティングするJavaScriptを作ればよい
  • エラー「Uncaught TypeError」が返ってくる場合は、スクリプトの埋め込み位置に間違いがないか確認する

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

タイトルとURLをコピーしました