キャッシュがサイト間で共有されない理由：ダブルキーキャッシュの解説

[![表紙](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/732e9400-4f43-10c0-2f19-13736d8bad89.png)](https://leapcell.io/?lc_t=q_dblkeycache)

あなたはこんな疑問を持ったことがありますか？

**「ウェブサイトの静的リソースはキャッシュされているのに、別のサイトを開くと再ダウンロードされるのはなぜ？」**

この現象の本質的な原因は **ダブルキーキャッシュ（Double-keyed Caching）** にあります。

そこで、今日は **ダブルキーキャッシュとは何か、どのように動作するのか、そしてどのように最適化できるのか** について話しましょう。

## ダブルキーキャッシュとは？

従来のブラウザキャッシュでは、リソースのキャッシュは **URL に基づいて** 保存されていました。

たとえば、**https://cdn.example.com/script.js** にアクセスすると、ブラウザはこの `script.js` をキャッシュし、他のサイトが同じ URL を参照した場合は、キャッシュを再利用して再ダウンロードを防ぎます。

この従来のキャッシュ方式は、理想的な動作のように見えます。つまり、「一度キャッシュされたリソースは、どのサイトからでもアクセスできる」というものです。

しかし、この方法には **重大なセキュリティリスク** が存在します。それは **クロスサイトトラッキング（Cross-site Tracking）** や **データ漏洩** の危険性です。

例えば：

- あるウェブサイトが、共通の CDN リソースのキャッシュ状態を確認することで、ユーザーが特定のサイトを訪問したかどうかを推測できる（広告トラッキングなど）。
- ハッカーが **キャッシュポイズニング（Cache Poisoning）** 攻撃を利用し、ユーザーに改ざんされたリソースを読み込ませる。

このようなセキュリティ問題を防ぐため、多くのブラウザ（**Chrome、Firefox など**）は **ダブルキーキャッシュ** を導入しました。

ダブルキーキャッシュの基本ルールは以下の通りです：

**リソースをキャッシュする際に、URL だけでなく「どのサイト（オリジン）で読み込まれたか」も考慮し、「オリジン + URL」をキャッシュの一意の識別子として扱う。**

つまり：

- **以前のキャッシュ方式：** サイト A がキャッシュしたリソースを、サイト B もそのまま利用できる ✅
- **ダブルキーキャッシュ：** サイト A がキャッシュしたリソースを、サイト B は再ダウンロードしなければならない ❌

## ダブルキーキャッシュの仕組み

**ダブルキーキャッシュ = オリジン（サイト） + リソース URL**

具体例を見てみましょう：

あなたが **ウェブページ A とウェブページ B** を訪問し、それらが同じ CDN リソース（**https://cdn.example.com/script.js**）を使用している場合を考えます。

### ① 従来のキャッシュ（シングルキーキャッシュ）

1. ウェブページ A で `script.js` を読み込むと、ブラウザはそのファイルをキャッシュ。
2. その後、ウェブページ B を訪問すると、ブラウザは同じ `script.js` のリクエストを検出し、**キャッシュから読み込む（ネットワークリクエストが不要になり、ロード速度が向上）**。

### ② ダブルキーキャッシュ

1. ウェブページ A で `script.js` を読み込むと、ブラウザはそのファイルを **「ウェブページ A 専用」** としてキャッシュ。
2. その後、ウェブページ B を訪問すると、ブラウザは **ウェブページ A のキャッシュを使わず、再ダウンロードを行う**。

つまり、**異なるサイトでは、同じリソースであっても個別にキャッシュする** 必要があります。

この方式は **セキュリティを強化** しますが、以下のようなデメリットもあります：

- **キャッシュの再利用率が低下**：同じリソースでも、異なるサイトごとに再ダウンロードが必要。
- **CDN の利点が減少**：従来、CDN（例：jsDelivr、UNPKG）を使うことで、複数サイト間でキャッシュを共有できたが、その効果が薄れる。
- **初回アクセス時のコスト増加**：同じリソースがローカルにキャッシュされていても、別のサイトでは再ダウンロードが必要になり、ページの初回読み込みが遅くなる。

## ダブルキーキャッシュの影響を最適化する方法

上記の問題を考慮し、ダブルキーキャッシュの影響を最小限に抑える方法を紹介します。

### ① Service Worker を活用する

**Service Worker を利用すれば、ローカルキャッシュを活用し、ネットワークリクエストを減らすことが可能です。**

例えば、以下のような `Cache API` を用いたコードを実装すると、ダブルキーキャッシュの影響を受けずにリソースをキャッシュできます：

```js
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      return response || fetch(event.request);
    })
  );
});
```

**Service Worker のキャッシュはダブルキーキャッシュの影響を受けない** ため、頻繁に使用する静的リソースは HTTP キャッシュではなく、Service Worker で管理すると良いでしょう。

### ② HTTP/3 を活用し、リクエストのオーバーヘッドを削減

ダブルキーキャッシュの影響で、同じユーザーが異なるサイトを訪問すると、CDN リソースが何度もダウンロードされます。

しかし、**HTTP/3（QUIC）** を使えば、**マルチプレクシング（多重化）** や **0-RTT（ゼロ往復時間）接続** を利用して、ネットワークオーバーヘッドを削減できます。

> **自分の CDN が HTTP/3 に対応しているかを確認する方法**
>
> Chrome DevTools の **Network** タブを開き、**Protocol** 列を確認。
> `h3` と表示されていれば、HTTP/3 で通信されています。

### ③ 重要なリソースを事前読み込みする

ブラウザのキャッシュに完全に依存できないため、**重要なリソースは明示的にプリロード** するのが有効です。

例えば、以下のように `<link rel="preload">` を使ってフォントやスクリプトを事前読み込みできます：

```html
<link
  rel="preload"
  href="https://your-cdn.com/fonts/Roboto.woff2"
  as="font"
  type="font/woff2"
  crossorigin="anonymous"
/>
```

この方法を使うことで、**ダブルキーキャッシュの影響でリソースが再ダウンロードされても、できるだけ高速に読み込めるようにする** ことができます。

## まとめ

ダブルキーキャッシュは **セキュリティ向上** のために導入された仕組みですが、**キャッシュの再利用が制限されることで、パフォーマンスに影響を及ぼす** 可能性があります。

そこで、**Service Worker の活用、HTTP/3 の利用、重要リソースのプリロード** などの方法を駆使し、影響を最小限に抑えることが重要です。

---

### [私たちはLeapcell、バックエンド・プロジェクトのホスティングの最適解です。](https://leapcell.io/?lc_t=q_dblkeycache)

[![Leapcell](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/eabc4a78-0f72-9f2d-67a6-d43e88da0a2c.png)](https://leapcell.io/?lc_t=q_dblkeycache)

[Leapcell](https://leapcell.io/?lc_t=q_dblkeycache)は、Webホスティング、非同期タスク、Redis向けの次世代サーバーレスプラットフォームです：

**複数言語サポート**

- Node.js、Python、Go、Rustで開発できます。

**無制限のプロジェクトデプロイ**

- 使用量に応じて料金を支払い、リクエストがなければ料金は発生しません。

**比類のないコスト効率**

- 使用量に応じた支払い、アイドル時間は課金されません。
- 例: $25で6.94Mリクエスト、平均応答時間60ms。

**洗練された開発者体験**

- 直感的なUIで簡単に設定できます。
- 完全自動化されたCI/CDパイプラインとGitOps統合。
- 実行可能なインサイトのためのリアルタイムのメトリクスとログ。

**簡単なスケーラビリティと高パフォーマンス**

- 高い同時実行性を容易に処理するためのオートスケーリング。
- ゼロ運用オーバーヘッド — 構築に集中できます。

[ドキュメントで詳細を確認！](https://docs.leapcell.io/)

[![Try Leapcell](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/05ceebf9-7a0a-8f46-6ed1-0e0e6ff74054.png)](https://leapcell.io/?lc_t=q_dblkeycache)

Xでフォローする：[@LeapcellHQ](https://x.com/LeapcellHQ)

---

[ブログでこの記事を読む](https://leapcell.io/blog/understanding-double-keyed-caching)