マガジン

「ゲームの更新をしたのに古い版が表示されます」:キャッシュの話

遊びを見つける

執筆にClaudeを使用しています。

遊ばれた回数、好意、感想を表す三種類の小さな札を比べる人の手。
記事のテーマをもとに制作したAI生成イラスト。

結論から答えます。更新したファイルがサーバーに届いていても、ブラウザーが前回保存した古いファイルを使い続けていると、古い版が表示されます。この保存の仕組みが「キャッシュ」です。対処は二段構えになります。遊ぶ側は再読み込みの種類を変えてみます。作る側は、更新のたびに参照するファイル名(URL)を変えます。後者が、この記事で言う「バージョン付きURL」です。 ただし、アソバースの配信側がキャッシュをどう扱っているか、更新が公開画面に反映されるまでに時間がかかるかどうかは、確認済みの情報にありません。この部分は現在の案内で確認してください。以下では、ブラウザー側で自分で確かめられること、作者側で制御できることに絞って答えます。 「古い」の中身も、先に分けておく必要があります。コードやHTMLそのものが古いのか、ゲームの中の保存データが古いのか、見分けないまま対処すると遠回りになります。

この記事の目次
  1. Q1. なぜ、更新したのに古い版が出るのですか
  2. Q2. 遊ぶ側が、まず試せることはありますか
  3. Q3. 作る側は、何を変えればよいですか
  4. Q4. 古いのがHTMLなのかJSなのか、どう切り分けますか
  5. Q5. 版は新しいのに、中身が古く見えるのはなぜですか
  6. 次の行動
  7. 参考資料

Q1. なぜ、更新したのに古い版が出るのですか

ブラウザーは、一度取得したHTML・JavaScript・画像などを手元に保存し、次回は通信せずに使うことがあります。通信を省けるので速くなりますが、サーバー側のファイルが変わっても気づけません。どのくらいの間、保存分を使ってよいかは、サーバーが返す情報(HTTPヘッダーのCache-Controlなど)で決まります。

アソバースのゲームは、サンドボックス付きのiframe(ページの中に別のページを埋め込む枠)で実行され、アップロードしたコードはメインサイトと別のオリジンから配信されます。つまり、見ている画面は「サイトの画面」と「その中のゲーム」の二重構造です。サイト本体が最新でも、中のゲームのファイルだけが保存分ということは、仕組みの上ではあり得ます。

もう一つ、作者側の構成にも原因が潜みます。アップロード作品の入口は直下のindex.htmlと決まっているため、入口のファイル名は変えられません。このindex.html自体が保存分だと、中で新しいファイル名を指していても、その記述が読まれません。これが、後で述べる設計の要点です。

Q2. 遊ぶ側が、まず試せることはありますか

再読み込みには強さの違いがあります。軽いほうから順に試します。

  1. 通常の再読み込み。ブラウザーによっては、保存分が使えるか確認する程度で済ませます。
  2. キャッシュを無視する再読み込み。一般には、WindowsならCtrl+Shift+RまたはCtrl+F5、MacならCommand+Shift+Rです。保存分を使わずに取り直す指示になります。
  3. 開発者ツールを使う方法。ブラウザーの開発者ツールを開き、Networkタブにある「Disable cache(キャッシュを無効化)」をオンにしたまま再読み込みします。ツールを開いている間だけ有効になるのが一般的です。

キー操作や名称はブラウザーごとに少しずつ違うため、お使いのブラウザーの案内で確認してください。また、ゲームはページ内の枠の中で動いているので、サイト全体の再読み込みで枠の中まで取り直されるかどうかは、画面で確かめる必要があります。直らない場合は3番を試し、それでも変わらなければ、次の切り分けに進みます。

保存分かどうかは、Networkタブで読み取れます。各ファイルの行に、通信せず手元から読んだことを示す表示(「disk cache」「memory cache」など)が出ていないかを見ます。表示の文言はブラウザーで異なります。

Q3. 作る側は、何を変えればよいですか

答えは、更新したファイルは別の名前で配ることです。ブラウザーの保存は「URLごと」に管理されます。URLが変われば、保存分と一致しないので、必ず取り直されます。これがバージョン付きURLの考え方です。

方法は大きく二つあります。

  • ファイル名に版を入れる方法です。game.js ではなく game.a4.js のようにします。画像や音声も同様にできます。ビルドツールがファイル内容から短い文字列(ハッシュ)を作り、名前に付ける方式も同じ考え方です。
  • クエリ文字列を付ける方法です。game.js?v=4 のように書きます。手軽ですが、配信経路によってはクエリを無視して同じ保存分を返す場合があります。確実さを求めるなら、ファイル名に入れるほうが無難です。

アップロード作品では、素材は相対パスで指定する決まりです。ZIPの中のファイル名を変え、index.html内の相対パスをそれに合わせて書き換える運用になります。index.htmlだけは名前を変えられないため、「HTMLは毎回確認され、中身(JS・画像)は名前を変えて配る」という分担になります。

ここで、作り手が見落としやすい点があります。

  • JSの名前だけ変えて、index.html内の参照を直し忘れる。
  • 逆に、index.htmlだけ更新して、同名の古いJSを残したまま上書きしていない。
  • 画像や音声は名前を変えず、JSだけ変える。

また、サービスワーカー(ブラウザー内に常駐してキャッシュを制御する仕組み)は、アップロード作品の対象外です。そのため、サービスワーカーが古い版を返し続けるという事態は、アップロードした作品の構成としては想定しなくて済みます。URL投稿の場合は、公開先サーバーの設定が作者の管理範囲になるので、そちらの設定を確認します。

Q4. 古いのがHTMLなのかJSなのか、どう切り分けますか

画面に版の印を出しておくのが、一番確実です。HTMLとJSそれぞれに同じ版の印を持たせ、画面に並べます。次の最小構成を、そのまま試せます。

index.html

html
<!doctype html>
<html lang="ja">
<meta charset="utf-8">
<title>版の確認</title>
<p>HTMLの版: <span id="h"></span></p>
<p>JSの版: <span id="j">未読み込み</span></p>
<script>
  var HTML_BUILD = "A3";
  document.getElementById("h").textContent = HTML_BUILD;
</script>
<script src="game.a3.js"></script>

game.a3.js

js
var JS_BUILD = "A3";
document.getElementById("j").textContent = JS_BUILD;

更新するときは、次の三つを同時に行います。game.a3.js を game.a4.js に改名し、中の JS_BUILD を "A4" にします。そして index.html の参照先と HTML_BUILD も "A4" にします。公開内容を更新したあと、ゲームを開いて表示を読みます。

  • HTML=A4、JS=A4、読み取れること:最新の版が表示されています。
  • HTML=A3、JS=A3、読み取れること:index.htmlが古い状態です。更新が反映前か、保存分が使われています。Q2の再読み込みを試します。
  • HTML=A4、JS=A3、読み取れること:古いJSが使われています。JSの名前を変えずに配っていないか、参照先を確認します。
  • JSが「未読み込み」のまま、読み取れること:新しい名前のファイルがZIPに入っていないか、パスが違う可能性があります。

試すときは、同じ手順を数回、通常の再読み込みとキャッシュ無視の再読み込みで繰り返し、表示がどう変わるかを記録します。更新後に何回の再読み込みで切り替わるかを、手元のメモに残しておくと、原因が保存分なのか反映待ちなのかを判断しやすくなります。反映待ちの有無は上で述べたとおり確認済みではないので、案内で調べてください。

Q5. 版は新しいのに、中身が古く見えるのはなぜですか

画面の版表示が最新なのに、進行状況や記録が古い場合は、キャッシュではなく保存データの問題です。確認済みの範囲で、次の点が関係します。

  • アップロードしたゲームにはSDKが自動で追加され、ログイン中はクラウドセーブ(作品ごとにJSONで128KiBまで)が使えます。
  • 未同期の端末セーブは、クラウドの古いデータより優先して再送されます。端末に残っていた古い内容が、クラウド側を上書きする方向に働く場面があり得ます。
  • ゲストの履歴・進行は端末内に保存され、ログイン後のアカウントへ自動では混ざりません。ログイン前後で別の進行に見えることがあります。
  • アップロード作品内のlocalStorage/sessionStorageは一時メモリーの互換処理です。永続的な保存先としては当てにしません。

作り手は、セーブデータに version を持たせ、読み込み時に古い形式を新しい形式へ変換する処理を入れておくと安全です。公式作品でも、古い保存(version1)が新しい形式(version2)へ移行すると案内されています。コードの版(A3・A4)とデータの版は別物なので、画面に両方を出すと見分けやすくなります。

次の行動

遊ぶ側は、まず「キャッシュを無視する再読み込み」を一度行い、直らなければ開発者ツールで保存分の表示を確認してください。作る側は、上の二つのファイルで、更新ごとに改名して表示が切り替わるかを手元で確かめてください。更新の反映までの時間や配信側の設定は、現在の案内で確認します。

参考資料

  • MDN Web Docs「HTTP キャッシュ」
  • MDN Web Docs「Cache-Control」