0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

表紙

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

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

この現象の本質的な原因は ダブルキーキャッシュ(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 を用いたコードを実装すると、ダブルキーキャッシュの影響を受けずにリソースをキャッシュできます:

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"> を使ってフォントやスクリプトを事前読み込みできます:

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

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

まとめ

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

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


私たちはLeapcell、バックエンド・プロジェクトのホスティングの最適解です。

Leapcell

Leapcellは、Webホスティング、非同期タスク、Redis向けの次世代サーバーレスプラットフォームです:

複数言語サポート

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

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

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

比類のないコスト効率

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

洗練された開発者体験

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

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

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

ドキュメントで詳細を確認!

Try Leapcell

Xでフォローする:@LeapcellHQ


ブログでこの記事を読む

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?