記事の目的
GitHub Pagesでサイトを公開する場合に、サイトを更新するたびに共有URLや記事を書き換えなくても済む方法として、思いついた比較的手軽な手法を3つ紹介することが、この記事の主な目的です。
ただし、キャッシュ対策として一般的に使われている方法も比較対象として載せた方が分かりやすいため、今回は全部で6つの方法を紹介します。
前述の3個の方法について
これら3つの方法は、HTML本体のキャッシュ回避には有効ですが、外部CSSや外部JavaScriptのキャッシュを直接回避するものではありません。
外部ファイルは、それぞれのURLごとに個別にキャッシュされます。
そのため、外部ファイルを更新する場合は、HTML側の参照URLも変更します。
<link rel="stylesheet" href="style.css?v=12">
<script src="app.js?v=12"></script>
例えばCSSを更新したら、v=12をv=13に変更します。
<link rel="stylesheet" href="style.css?v=13">
前述の方法でHTML本体のキャッシュを回避できれば、更新後のvの値を含むHTMLを取得しやすくなります。
ただし、v=12のまま外部ファイルだけを更新した場合は、外部ファイルのキャッシュが残る可能性があります。
3個の方法のデメリットについて
3個の方法は、クエリパラメータを自動付与する事で回避を試みます。
そのため、キャッシュ回避の能力は強いのですがユーザー側はキャッシュが無駄に蓄積される可能性があります。
弱めのデメリットである可能性もありますが、念のため知っておく必要があります。
キャッシュの影響とは
Webサイトを更新したのに、閲覧者には古い内容が表示されることがあります。
これは、ブラウザやCDNのキャッシュが原因の場合があります。
紹介する手法の知名度について
今回は、公開サイトでキャッシュの影響を減らす方法を6つ紹介します。
3の中継サイトを使う方法については、同じ目的のサービスを検索した範囲では、すぐには見つけられませんでした。
5の自動付与については、使っている技術自体は知られているものですが、この形での使い方が広く知られているとは言いにくそうです。
6の専用中継サイトを作る については、作るのが若干手間です。
特に5はブックマークで直接アクセスした場合も有効です。
その代わり容量が単純に2倍になると言って良いため、ユーザー側の負担は増えます。
それ以外の方法は、比較的一般的な手法です。
1. Cache-Control: no-cache を設定する
サーバー側で設定できる場合は、一番自然な方法です。
Cache-Control: no-cache
これはキャッシュ自体を完全に禁止するのではなく、キャッシュを再利用する前にサーバーへ更新確認を行わせる設定です。
URLが通常のままなので、ユーザー視点でも安心感があります。
「古い内容をできるだけ表示させたくない」という目的では、no-store より no-cache の方が適している場合があります。
ただし、利用しているホスティングサービスによっては設定できません。
2. URLにバージョン情報を付ける
例えば、
https://example.com/page.html?ver=21
のように、更新時にクエリパラメータを変更します。
URLが変わるため、古いキャッシュを参照されにくくなります。
ただし、更新するたびに、
ver=21
ver=22
ver=23
または、
siteversion=21
siteversion=22
siteversion=23
のように変更する必要があります。
ユーザーから見るとURLが少し特殊になりますが、比較的分かりやすい方法です。
3. 毎回クエリパラメータを付けて遷移するサイトを使う
例えば、
キャッシュ対策用URL
↓
https://example.com/page.html?現在時刻
のように、アクセスするたびに異なるクエリパラメータを付けて、目的のサイトへ遷移させます。
毎回URLが変わるため、キャッシュの影響をかなり受けにくくできます。
一度キャッシュ対策用URLを作れば、サイト更新時に共有URLを変更する必要はありません。
一方で、別サイトを経由するため、ユーザーから見ると5つの方法の中では最も不安を感じやすい方法です。
👇 キャッシュ対策用URL作成サイト
例えば、
[Markdown から資料を作るサイト](https://uni928.github.io/Uni928PublicHTMLs2/index15.html?uni928.github.io/Uni928PublicHTMLs/index80.html)
のように書けば、実際の記事上では通常のリンク文字列として表示できます。
URLを確認する人には中継サイトであることが分かるため多少の不安は残りますが、URLを直接確認しない人には普通のリンクとして見えるため、全体としては不安感をある程度軽減できると思います。
同様の目的で使える中継サイトは、検索した範囲では見つからなかったため、自分で作成しました。
後で述べますが、この中継サイトのHTMLをご自身のGitHub Pagesなどに公開して利用することも可能です。
4. 新しいファイル名でアップロードする
例えば、
page21.html
page22.html
page23.html
のように、更新するたびに別ファイルとして公開します。
URLそのものが変わるため、非常に分かりやすいキャッシュ対策です。
ユーザーから見ても通常のURLなので、安心感があります。
ただし、ファイル名の変更・アップロード・共有URLの変更が毎回必要になるため、最も手間がかかります。
ブックマークした人のために、旧データは残しておくか、リダイレクト処理をする必要があります。
5. サイト自体に自動付与の仕組みを入れる
サイトを作る最初の段階から、titleタグ metaタグ群の直後に次の script を入れておく方法です。
<script>
(() => {
try {
const now = Date.now();
const cacheLimit = 5 * 60 * 1000;
const storageKey = 'html_cache_bust_time';
const cacheParam = '_cb';
const lastTime = Number(sessionStorage.getItem(storageKey)) || 0;
const url = new URL(location.href);
const currentCacheValue = url.searchParams.get(cacheParam);
// 5分以上経過している場合だけキャッシュバスト
if (now - lastTime >= cacheLimit) {
sessionStorage.setItem(storageKey, String(now));
url.searchParams.set(cacheParam, String(now));
location.replace(url.href);
return;
}
// キャッシュバスト後はURLから _cb だけ削除
if (currentCacheValue !== null) {
url.searchParams.delete(cacheParam);
history.replaceState(
history.state,
'',
url.pathname + url.search + url.hash
);
}
} catch (error) {
console.error(error);
}
})();
</script>
を入れる事で、HTML本体のキャッシュを回避する事が出来ます。
外部スクリプトを入れる必要性は感じませんが、
<script src="https://uni928.github.io/Uni928PublicHTMLs2/Plugin/plugin1.js"></script>
でも動作します。
アクセスすると、自動的に Date.now() を付けたURLへ移動します。
例えば、
https://example.com/page.html
へアクセスした場合に、
https://example.com/page.html?現在時刻
のようなURLへ移動します。
この方法なら、共有URLや記事を書き換える必要がありません。
また、中継サイトを使わないため、ユーザーから見ても通常のサイトURLのまま共有できます。
ただし、後からこの処理を追加する場合、それ以前のHTMLがキャッシュされていると、新しく追加した処理自体が読み込まれない可能性があります。
そのため、この方法を使う場合は、できればサイト公開時から入れておくのが安全です。
6. 専用の中継サイトを作る
そのURL専用の中継サイトを作る方法もあります。
そうする事でユーザー側の通信料を抑える事が期待できます。
中継サイト側には、遷移先へ現在時刻を付けて移動する処理だけを書きます。
<!doctype html>
<meta charset="utf-8">
<script>
const target = new URL(
'https://example.com/page.html'
);
target.search = '?' + Date.now();
location.replace(target.href);
</script>
既存のクエリパラメータを保持したまま、Date.now()を追加できます。
中継サイト側は中継処理だけで構成できるため、遷移先のURLを毎回書き換えずに利用できます。
また、例えば
https://sample.com/price/
部分が共通ならば、
https://sample.com/price/mover.html#demo/index2.html
的なアクセスの仕方で
https://sample.com/price/demo/index2.html
にアクセスするという中継サイトも作る事ができます。
どの手法が優れているか
| 方法 | 更新時の手間 | ユーザー視点 |
|---|---|---|
no-cache |
少ない | 安心 |
?ver=21 などを付与 |
少し必要 | 少し特殊 |
| 自動でクエリを付けて遷移 | 少ない | やや不安 |
| 新しいファイル名で公開 | 多い | 安心 |
| サイト自身に自動付与を仕込む | なし | 安心 |
| 専用中継サイトを作る | なし | やや不安 |
サーバー側で設定できるなら、まず no-cache などのキャッシュ制御を検討するのが自然です。
それが難しい静的サイトでは、バージョン付きURL・中継サイト・自動クエリ付与・ファイル名変更などを用途に応じて使い分けるとよいと思います。
特に、
- GitHub Pagesを使いたい
- 共有URLを変えたくない
- 記事内のリンクを更新のたびに書き換えたくない
という場合には、3または5または6の方法が使いやすいと思います。
特に5が良いと思います。
これ以降は、特にセキュリティを重視する方に向けた内容です。
コードを確認したい方・セキュリティを重視する方
👇 GitHub
GitHubのURLは、悪意のあるコードが含まれていないか、ご自身で目視確認したい方向けに公開しています。
網羅的な確認はできませんが、ChatGPTなどにコードを添付して、悪意のある処理や不審な通信が含まれていないか確認してもらう方法もあります。
ご自身が使いやすいように、ChatGPTなどを活用してチューニングしてから利用することも可能です。
チューニングの有無にかかわらず、ご自身のGitHub Pagesやサーバーにアップロードして運用する方法も、外部の中継サイトへの依存を避けられるため選択肢の一つです。
より使いやすいサイトを作成できた場合は、私も利用してみたいので、公開していただけるとうれしいです。
なお、全面的に作り直したものではなく、本リポジトリを改造して作成したものを公開する場合は、MITライセンスの条件に従って公開してください。