OpenAICloudflare2026/04/17 13:02

Shared Dictionaries: compression that keeps up with the agentic web

要点だけを先に読めるように短く再構成したセクションです。

元記事

Quick Digest

要約

要点だけを先に読めるように短く再構成したセクションです。

openaijamodel: gpt-5-mini-2025-08-07

共有辞書:エージェント主導のウェブに追いつく圧縮

Key Points

  • ベータは2026-04-30開始予定
  • ラボで最大97%転送削減
  • Chrome/Edge 130+が必要

Summary

共有辞書(RFC 9842準拠)は、ブラウザが既にキャッシュしている以前のリソースを辞書として使い、サーバーが差分だけを送ることで転送量と読み込み時間を劇的に削減します。エージェントによるリクエスト増加と頻繁なデプロイでキャッシュ効果が失われる現状に対して、CDN側での辞書対応は現実的かつ効果的な対策です。Cloudflareは段階的にサポートを展開し、まずはパススルー(Phase 1)のベータを4月30日に導入します。

Key Points

  • 概要

    • 共有辞書はクライアントが持つ古いバージョンをそのまま辞書にして差分(delta)を送信。
    • RFC 9842が過去のSDCHでの問題(サイドチャネルや同一生成ポリシー違反)を是正し、同一オリジン制約などで安全性を高めている。
  • Phase 1(パススルー、ベータ 2026-04-30)— エンジニア向け要件

    • Cloudflareゾーンで機能を有効化すること。
    • オリジンは Use-As-Dictionary ヘッダと Content-Encoding: dcb または dcz を付けて辞書圧縮済レスポンスを返すこと。
    • ブラウザ互換:Chrome 130+、Edge 130+(Firefoxは対応進行中)。
    • Cloudflareは Use-As-Dictionary / Available-Dictionary ヘッダと dcb/dcz エンコーディングを透過し、キャッシュキーは Available-Dictionary と Accept-Encoding を考慮して変化させる。
  • 運用上の注意点

    • キャッシュはエンコーディング×辞書ハッシュごとにバリアントが増え、ヒット率やストレージに影響するため監視が必要。
    • オリジンでの差分圧縮が遅い場合、TTFBはgzip比で約20ms程度遅くなることがあるが、実測ではダウンロード時間で大幅に改善する(ラボ例を参照)。
  • ラボ実測(参考)

    • 元ファイル: 272KB → gzip: 92.1KB → DCZ(前バージョン辞書): 2.6KB(gzip比で約97%削減)
    • タイミング: キャッシュミス時ダウンロード 31ms vs gzip 166ms(約81%改善)、キャッシュヒット時 16ms vs 143ms(約89%改善)。
  • セキュリティと実装の複雑さ

    • RFC 9842は同一オリジン制約などでCRIME/BREACH型のリスクを緩和。ただし辞書管理、キャッシュ変種、フォールバックロジックなど実装は複雑でCDN側での調整が重要。
  • 今後(Phase 2以降)

    • Phase 2ではCloudflareが辞書の生成・注入・保管・差分圧縮を代行するルールベースの管理を予定。エンジニアは対象アセット指定と運用監視に集中可能になる見込み。

Actionable checklist for engineers

  • ベータに向けて:ゾーンで機能を有効化し、オリジンで Use-As-Dictionary と dcb/dcz を返す検証を行う。
  • ブラウザ互換性を確認(Chrome/Edge 130+)、Firefox対応状況を追跡する。
  • キャッシュ比率・ストレージ増加を監視するメトリクスを追加する(辞書ハッシュ別のヒット率など)。
  • 実運用前に小さなバンドル差分でラボ試験を行い、実際の圧縮率と遅延トレードオフを測定する。

Full Translation

翻訳

原文の流れを保ったまま読める翻訳セクションです。

openaijamodel: gpt-5-mini-2025-08-07

共有辞書:エージェント化されたウェブに追いつく圧縮

概要

Webページは過去10年間、年率で6–9%ずつ重くなってきました。フレームワーク依存度の上昇、対話性の増加、メディアのリッチ化がその主な要因です。この傾向自体は変わりませんが、ページが再構築される頻度とそれを要求するクライアント数が急増しています。どちらもエージェントの台頭により爆発的に増えています。

共有辞書(shared dictionaries)は、サーバーからブラウザへのアセット転送を縮小し、特にリターンユーザーや低速回線の訪問者に対してページの読み込みを高速化し、ワイヤ上の冗長バイトを削減します。デプロイごとに完全なJavaScriptバンドルを再ダウンロードする代わりに、ブラウザが既にキャッシュしているものをサーバーに伝え、サーバーはファイルの差分のみを送信します。

本稿では、共有圧縮辞書のサポートについての先行プレビュー、初期テストで見えてきたこと、そしてベータを試せる日(ヒント:2026-04-30)をお伝えします。

問題:より頻繁に送る=キャッシュが効かない

エージェント化されたクローラーやブラウザなどがエンドポイントを何度も叩き、ページ全体を取得してその一部の情報を抜き出すケースが増えています。エージェントは2026年3月のCloudflareネットワーク全体のリクエストの約10%弱を占め、前年同期比で約60%増加しました。

さらに、エージェントは単にウェブを消費するだけでなく、ウェブ構築にも寄与しています。AI支援の開発によりチームの出荷頻度は速まり、デプロイや実験、反復が増えますが、それはキャッシュにとっては最悪です。エージェントがワンラインの修正を行うと、バンドラが再チャンクされ、ファイル名が変わり、ブラウザは全ユーザーに対してアプリ全体を再ダウンロードする可能性があります。コード自体が本質的に変わっていなくても、ブラウザは新しいURLを見て最初から取得し直すからです。

従来の圧縮は各ダウンロードのサイズには効果がありますが、冗長性(クライアントがファイルの95%を既にキャッシュしていることなど)には対応できません。したがって、デプロイごとに、すべてのユーザーとすべてのボットに対して冗長なバイトが何度も送信されます。1日に小さな変更を10回出荷すると、実質的にキャッシュを放棄したのと同じことになります。ハードウェアがボトルネックになりつつあるウェブで、これは帯域とCPUの無駄遣いです。

より多くのリクエストがより重いページに押し寄せ、しかもそれらがより頻繁に再デプロイされる現実にスケールするには、圧縮はもっと賢くなる必要があります。

共有辞書とは何か?

圧縮辞書は、サーバーとクライアントが共有するリファレンス(チートシートのようなもの)です。サーバーはレスポンスをゼロから圧縮する代わりに「このファイルのこの部分はあなたが以前キャッシュしているから知っているはずだ」とみなし、新しい部分だけを送ります。クライアントは同じリファレンスを持っており、解凍時にそれを使って完全なレスポンスを再構築します。辞書がファイル中のコンテンツを多く参照できるほど、転送される圧縮出力は小さくなります。

この「既に知られているものに対して圧縮する」原理は、現代の圧縮アルゴリズムが旧来のものより優れる理由です。BrotliはHTML属性やよくあるフレーズなどの組み込み辞書を持ちます。Zstandardはカスタム辞書向けに設計されており、代表的なコンテンツサンプルを与えると最適化された辞書を生成します。Gzipはこれらを持たず、圧縮時にリアルタイムでパターンを見つけて辞書を構築します。これらの「従来型圧縮」は現在Cloudflareでも利用可能です。

共有辞書はこの原理をさらに一歩進めます:以前キャッシュされたリソース自体を辞書にするのです。先述の「ワンライン修正で全員がフルバンドルを再ダウンロードする」問題を思い出してください。共有辞書では、ブラウザが古いバージョンを既にキャッシュしています。サーバーはそれに対して圧縮し、差分のみを送ります。500KBのバンドルがワンラインの変更であれば、ワイヤ上ではほんの数KBになります。日間100Kユーザーで1日に10回デプロイすると、転送が500GBと数百MBの差になります。

デルタ圧縮

デルタ圧縮は、ブラウザが既に持っているバージョンを辞書に変換する仕組みです。プロトコルでは、サーバーが最初にリソースを返すときに Use-As-Dictionary レスポンスヘッダーを付けて、ブラウザにそのファイルを保持しておくよう指示します。次にそのリソースを要求する際、ブラウザは Available-Dictionary ヘッダーを返し、「これが私の持っている辞書です」とサーバーに伝えます。サーバーは新しいバージョンを古いバージョンに対して圧縮し、差分だけを送信します。別ファイルとしての辞書は不要です。

この仕組みは実アプリケーションで大きな効果をもたらします。バージョン管理されたJSバンドル、CSSファイル、フレームワークのアップデートなど、リリース間で段階的に変化するものに最適です。ブラウザが app.bundle.v1.js をキャッシュしており、開発者が app.bundle.v2.js をデプロイした場合、デルタ圧縮はその2つの差分だけを送ります。以後のバージョンもそれぞれ直前のバージョンに対する差分のみです。節約効果はリセットされず、リリース履歴全体にわたって継続します。

また、非静的コンテンツに対するカスタム/動的な辞書についてコミュニティ内で活発な議論があります。これは将来的な作業領域で、示唆に富む影響が期待されます。

では、なぜ今まで普及しなかったのか?

共有辞書が強力なら、なぜ既に広く使われていないのでしょうか?過去に試行された際、実装がオープンウェブと接触したときに耐えられなかったからです。Googleは2008年にChromeで Shared Dictionary Compression for HTTP (SDCH) を導入しました。初期の導入者ではページロード時間が二桁改善されたという報告もありましたが、SDCHは問題を次々に累積しました。

最も記憶される問題は圧縮サイドチャネル攻撃(CRIME、BREACH)のクラスです。研究者たちは、攻撃者がセッションCookieやトークンなどの機密と一緒にコンテンツを注入できる場合、圧縮後の出力サイズからその機密情報が漏れる可能性を示しました。攻撃者は1バイトずつ推測し、アセットサイズが縮むかどうかを観察して繰り返すことで、秘密を徐々に抽出できます。

しかし、セキュリティだけが問題ではなく、採用が進まなかった主因でもありません。SDCHはSame-Origin Policyを破る設計などいくつかのアーキテクチャ上の問題を露呈しました(皮肉にもこれが高性能の一因でもありました)。クロスオリジン辞書モデルはCORSと整合せず、Cache APIのような仕組みとの相互作用に関する仕様も不足していました。やがて採用の準備が整っていないことが明らかになり、2017年にChrome(当時の唯一の対応ブラウザ)はSDCHを撤回しました。

その後、ウェブコミュニティがバトンを受け取るまでに10年かかりましたが、現在の標準である RFC 9842: Compression Dictionary Transport は、SDCH を実用不可能にした主要な設計上のギャップを埋めています。例えば、広告された辞書は同一オリジンのレスポンスでのみ使用可能と強制し、サイドチャネル圧縮攻撃を可能にしていた多くの条件を防ぎます。Chrome と Edge はサポートを実装済みで、Firefox も追従中です。標準は広範な採用に向かって動いていますが、ブラウザ間での完全なサポートはまだ整っていません。

RFC はセキュリティ上の問題を軽減しますが、辞書転送の実装は複雑です。オリジンは辞書を生成し、適切なヘッダーで提供し、各リクエストの Available-Dictionary を照合し、レスポンスをオンザフライでデルタ圧縮し、辞書を持たないクライアントにはフォールバックしなければならないかもしれません。キャッシュも複雑になります。レスポンスはエンコーディングと辞書ハッシュの両方で変動するため、辞書の各バージョンが別個のキャッシュバリアントを生みます。デプロイ中は古い辞書を持つクライアント、新しい辞書を持つクライアント、辞書を持たないクライアントが混在します。ヒット率は下がり、ストレージは増え、辞書自体も通常のHTTPキャッシュルールの下で新鮮さを保たねばなりません。

この複雑さは調整の問題です。そしてまさに“エッジ”で処理されるべき種類の問題でもあります。CDNはすでに全てのリクエストの前に位置し、圧縮を管理し、キャッシュのバリアントを扱っています(近いうちにこの分野の発表ブログを公開予定です)。

Cloudflareが共有辞書サポートをどう構築しているか

共有辞書圧縮はブラウザとオリジンの間のスタック層すべてに触れます。強い顧客の関心が寄せられており、既に独自実装を構築する人もいます。たとえばRFCの著者 Patrick Meenan の dictionary-worker は、Cloudflare Worker 内で WASM-compiled Zstandard を使って辞書ライフサイクル全体を実行します。

私たちはこれを誰にでも使いやすくしたいと考え、プラットフォーム全体で3つのフェーズに分けて展開しています。まずは配線(plumbing)から始めます。

Phase 1 : パススルーサポート(開発中)

  • Cloudflare は Use-As-DictionaryAvailable-Dictionary といった共有辞書が必要とするヘッダーや、dcbdcz のコンテンツエンコーディングを、無変更で転送します(剥ぎ取り、改変、再圧縮は行いません)。
  • キャッシュキーは Available-DictionaryAccept-Encoding によってバリアブルになるよう拡張され、辞書圧縮されたレスポンスが正しくキャッシュされるようにします。
  • このフェーズは、オリジン側で自分たちの辞書を管理するお客様向けです。

公開ベータは 2026-04-30 に予定しています。利用条件の一例は次の通りです:Cloudflare ゾーンでこの機能が有効になっていること、オリジンが辞書圧縮レスポンスを正しいヘッダー(Use-As-DictionaryContent-Encoding: dcb または dcz)で返すこと、訪問者のブラウザが dcb/dczAccept-Encoding に広告し Available-Dictionary を送信すること。現時点では Chrome 130+ と Edge 130+ が該当し、Firefox のサポートは進行中です。利用可能になった際は changelog をチェックしてください。より詳しい利用方法のドキュメントも提供します。

Phase 1 の初期社内テスト

内部の制御テストでは、ほぼ同一の2つの JS バンドルを順にデプロイしました(バージョン間で局所的な差分のみ)。

  • 未圧縮のアセットサイズ:272KB
  • gzip:92.1KB(約66%削減)
  • 共有辞書圧縮(DCZ、前バージョンを辞書として使用):2.6KB(既に圧縮されたアセットに対してさらに97%の削減)

クライアント側で計測した2つのタイミング指標:TTFB(time to first byte)と完全ダウンロード完了時間の結果も報告します。TTFBは示唆深い点があります。キャッシュミス(DCZがオリジンで辞書に対して圧縮する場合)では、TTFBはgzipより約20ms遅くなるだけで、伝送のオーバーヘッドはほとんど無視できるレベルでした。ダウンロード完了時間に差が出ます。キャッシュミス時で DCZ は31ms、gzip は166ms(81%の改善)。キャッシュヒット時は16ms対143ms(89%の改善)。レスポンスが非常に小さいため、開始時にわずかなペナルティを払っても、トータルでは大きく先行します。

これらは最小限のJSバンドル差分を想定したラボの初期結果であり、実際の節約量は辞書とアセット間のデルタによって変動します。

Phase 2 : Cloudflareによる管理(概要、ここから続きます)

Phase 2 では、オリジン側で辞書ヘッダーや圧縮、フォールバックロジックを操作する代わりに、どのアセットを辞書として使うかをルールで Cloudflare に指示すると、Cloudflare 側でそれらを管理します。私たちは Use-As-Dictionary ヘッダーの注入、辞書バイトの保存、そして新しいバージョンのデルタ圧縮を行います(本文はここで切れています)。

注:本文はソースの途中で切れているため、Phase 2 以降の詳細は原文の続きまたは今後のドキュメントを参照してください。

共有辞書:エージェント化されたウェブに追いつく圧縮 | Cloudflare | DocsDigest