Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Shared Dictionaries:跟得上 agentic web 的压缩

原文:Shared Dictionaries: compression that keeps up with the agentic web Source: https://blog.cloudflare.com/shared-dictionaries/

2026-04-17

过去十年,网页每年都 变重 6-9%,起因于 web 越来越框架化、交互化、富媒体化。这条轨迹不会改变。正在 改变的是,这些页面被重新构建的频率,以及请求它们的客户端数量。两者都因 agents 而暴涨。

Shared dictionaries 缩小了从服务器到浏览器的资产传输,让页面 加载更快、传输上更轻 —— 尤其对回访用户或慢速连接的访客。浏览器不再在每次部署后重新下载整个 JavaScript bundle,而是告诉服务器它已经缓存了什么,服务器只发送文件的 diff。

今天,我们激动地分享我们对 shared compression dictionaries 支持的预览,展示我们在早期测试中看到的成果,并揭晓你将能亲自尝试 beta 的时间(提示:就是 2026 年 4 月 30 日!)

问题:发布越多 = 缓存越少

Agentic 爬虫、浏览器和其他工具反复打到同一些端点,常常是为了提取一小段信息而抓取整个页面。2026 年 3 月,agentic 行为者占 Cloudflare 网络全部请求的近 10%,同比上升约 60%。

每个发布出去的页面都比去年更重,而被机器读取的次数也前所未有。但 agents 不只是消费 web,它们也在帮助构建 web。AI 辅助开发 意味着团队发布更快。提高部署、实验和迭代的频率对产品速度而言很棒,对缓存而言却很糟糕。

随着 agents 推一个一行的修复,bundler 重新切分,文件名变化,地球上的每个用户都可能重新下载整个应用。不是因为代码有什么实质不同,而是因为浏览器/客户端无从知道究竟变了什么。它看到一个新 URL,就从零开始。传统压缩有助于减小每次下载的体积,但它无法解决冗余 —— 它不知道客户端已经缓存了文件 95% 的内容。所以每次部署,对每个用户、每个 bot,都一遍遍发送冗余字节。一天发十个小改动,你就等于退出了缓存。在硬件迅速成为瓶颈的 web 中,这浪费带宽和 CPU。

为了在更多请求打到更重的页面、且这些页面被更频繁重新部署的情况下扩展,压缩必须变得更聪明。

什么是 shared dictionaries?

compression dictionary 是服务器和客户端之间的共享引用,它的作用就像一张小抄。服务器不再从零开始压缩响应,而是说“你已经知道这部分文件了,因为之前缓存过“,然后只发送新的内容。客户端持有同样的引用,并在解压时用它重建完整响应。dictionary 能引用文件中的内容越多,传输给客户端的压缩输出就越小。

利用“针对已知内容压缩“的原则,正是现代压缩算法领先于前辈的方式。Brotli 内置了一份常见 web 模式的 dictionary,如 HTML 属性和常用短语;Zstandard 则是为自定义 dictionary 量身打造:你可以喂给它代表性的内容样本,它会为你提供的内容类型生成一个优化的 dictionary。Gzip 两者都没有;它必须在压缩时实时寻找模式来构建 dictionary。这些“传统压缩“算法在 Cloudflare 今天就已 可用

Shared dictionaries 把这一原则又向前推进一步:资源此前缓存的版本变成 dictionary。还记得团队推一个一行的修复、每个用户都要重新下载完整 bundle 的部署问题吗?有了 shared dictionaries,浏览器已经缓存了旧版本。服务器对它进行压缩,只发送 diff。那个 500KB 的 bundle 含一行更改,在传输上只有几 KB。10 万日活、每天 10 次部署,差别就是 500GB 传输与几百 MB 之间的差距。

Delta compression

Delta compression 把浏览器已有的版本变成 dictionary。该协议的工作方式是:服务器首次提供资源时,附上一个 Use-As-Dictionary 响应头,告诉浏览器把这个文件留着,因为以后会有用。当下一次请求该资源时,浏览器返回一个 Available-Dictionary 头,告诉服务器“这是我已有的“。然后服务器对新版本相对旧版本进行压缩,只发送 diff。不需要单独的 dictionary 文件。

这正是真实应用获得回报的地方。带版本的 JS bundle、CSS 文件、框架更新,以及任何在发布之间增量变化的资源。浏览器已缓存 app.bundle.v1.js,开发者做了更新并部署 app.bundle.v2.js。Delta compression 只发送两版之间的 diff。后续每个版本同样只是 diff。版本三对版本二压缩。版本 47 对版本 46 压缩。节省不会清零,而是贯穿整个发布历史。

社区中也在积极讨论用于 非静态 内容的自定义和动态 dictionary。这是未来工作,但意义重大。我们留待另一篇博客再讲。

那为什么等这么久?

如果 shared dictionaries 这么强大,为何不是所有人都已在用?

因为上一次尝试时,实现没能在开放的 web 中存活。

Google 在 2008 年 把 Shared Dictionary Compression for HTTP(SDCH)在 Chrome 中上线。它确实有效,一些早期采用者报告页面加载时间获得两位数百分比的改善。但 SDCH 积累问题的速度比任何人能修的速度都快。

最难忘的是一类压缩侧信道攻击(CRIMEBREACH)。研究者展示,如果攻击者能在一个被压缩的、含敏感信息(如 session cookie、token 等)的内容旁注入内容,压缩输出的体积可以泄露关于秘密的信息。攻击者可以一次猜一个字节,观察资产体积是否缩小,反复直到提取出整段秘密。

但安全并非唯一问题,甚至不是采用没起来的主要原因。SDCH 暴露了一些架构问题,比如违反 Same-Origin Policy(讽刺的是这部分原因正是它表现这么好)。它的跨源 dictionary 模型 无法与 CORS 调和,也缺少与 Cache API 等交互的相关规范。一段时间后,大家明白普及还没就绪,于是 2017 年 Chrome(当时唯一支持的浏览器)下线了它

让 web 社区接过接力棒花了十年,但这是值得的。

现代标准 RFC 9842: Compression Dictionary Transport 弥补了让 SDCH 难以为继的关键设计漏洞。例如,它强制要求一个被广播的 dictionary 只能用于同源响应,防止许多让侧信道压缩攻击成为可能的条件。

Chrome 与 Edge 已支持,Firefox 正在跟进。该标准正走向广泛采用,但完整的跨浏览器支持仍在追赶中。

RFC 缓解了安全问题,但 dictionary transport 在实现上一直复杂。一个源站可能必须生成 dictionary、用正确的头部提供它们、检查每个请求的 Available-Dictionary 匹配、即时进行 delta 压缩响应,并在客户端没有 dictionary 时优雅降级。缓存也变得复杂。响应在 encoding 和 dictionary hash 上都会变化,所以每个 dictionary 版本都会创建一个独立的缓存变体。在部署中途,你既有用旧 dictionary 的客户端,也有用新 dictionary 的,还有没 dictionary 的。你的缓存为每种各存一份。命中率下降,存储攀升,而 dictionary 本身还要遵守正常的 HTTP 缓存规则保持新鲜。

这种复杂性是一个协调问题。也正是属于 edge 的事情。CDN 已经位于每个请求之前,已经管理压缩,也已经处理缓存变体(请关注此处即将到来的发布博客)。

Cloudflare 如何构建 shared dictionary 支持

shared dictionary 压缩涉及浏览器与源站之间堆栈的每一层。我们已经看到客户的强烈兴趣:有些人已经构建了自己的实现,例如 RFC 作者 Patrick Meenandictionary-worker,它在 Cloudflare Worker 内部使用 WASM 编译的 Zstandard 运行完整的 dictionary 生命周期(作为示例)。我们希望让所有人都能用上,并尽可能容易实现。所以我们分三个阶段在平台上推出,从管道铺设开始。

Phase 1:passthrough 支持目前正在开发。Cloudflare 转发 shared dictionaries 所需的头部和编码,如 Use-As-DictionaryAvailable-Dictionary,以及 dcbdcz 内容编码,不剥离、不修改、不重新压缩。Cache key 被扩展为按 Available-DictionaryAccept-Encoding 变化,以便正确缓存 dictionary 压缩的响应。这一阶段服务那些在源站自管 dictionary 的客户。

我们计划在 2026 年 4 月 30 日 之前推出 Phase 1 的公开 beta。要 使用它,你需要在已启用该功能的 Cloudflare zone 上,有一个能用正确的头部(Use-As-Dictionary、Content-Encoding: dcbdcz)提供 dictionary 压缩响应的源站,并且你的访客需要使用在 Accept-Encoding 中宣告 dcb/dcz 并发送 Available-Dictionary 的浏览器。今天这意味着 Chrome 130+ 与 Edge 130+,Firefox 支持正在进行中。

请密切关注 changelog,它何时上线以及如何使用的更多文档。

我们已经开始内部测试 passthrough。在一项受控测试中,我们顺序部署了两个 js bundle。它们几乎相同,只在表示同一 web 应用的连续部署的版本之间有少量本地化更改。未压缩时,该资产 272KB。Gzip 把它降到 92.1KB,减少 66%,相当不错。使用 shared dictionary compression over DCZ,以前一版本作为 dictionary,同一资产降到 2.6KB。这是在已经压缩的资产上再减少 97%

在同一实验室测试中,我们从客户端测量了两个时间里程碑:time to first byte(TTFB)和完整下载完成时间。TTFB 的结果有趣之处在于它没显示什么。在缓存未命中(DCZ 必须在源站对 dictionary 进行压缩)时,TTFB 仅比 gzip 慢约 20ms。传输上的开销几乎可以忽略不计。

差别在下载时间上。缓存未命中时,DCZ 用 31ms 完成,而 gzip 用 166ms(改善 81%)。缓存命中时,16ms 对 143ms(改善 89%)。响应小得多,即使你在开始时付出小小代价,完成时也远远领先。

初步实验室结果模拟最小 JS bundle diff,实际结果因 dictionary 与资产之间的真实 delta 而异。

Phase 2:这是 Cloudflare 开始替你做事的阶段。无需在源站处理 dictionary 头部、压缩和回退逻辑,在这一阶段,你通过一条规则告诉 Cloudflare 哪些资产应作为 dictionary,我们替你管理其余部分。我们注入 Use-As-Dictionary 头部、存储 dictionary 字节、对新版本相对旧版本进行 delta 压缩、并向每个客户端提供正确的变体。你的源站正常返回响应。任何 dictionary 复杂性都从你的基础设施转移到我们的。

为了演示这一点,我们构建了一个实时 demo。点这里试试: Can I Compress (with Dictionaries)?

该 demo 每分钟部署一个新的约 94KB 的 JavaScript bundle,旨在模拟一个典型的生产单页应用 bundle。代码大部分在部署间保持静态;每次只有一小块配置变化,这也反映了真实部署中绝大部分 bundle 是不变的框架和库代码。当首版加载时,Cloudflare 的 edge 把它存为 dictionary。下一次部署到达时,浏览器发送它已有版本的哈希,edge 用它对新 bundle 做 delta 压缩。结果:94KB 压缩到约 159 字节。这是 相对 gzip 减少 99.5%,因为线上传输的只有真正的 diff。

demo 站点包含分步指南,你可以通过 curl 或浏览器自己验证压缩比。

Phase 3:dictionary 自动代表网站生成。客户不再需要指定哪些资产作为 dictionary,Cloudflare 自动识别。我们的网络已经看到流经的每种资源的每个版本,涵盖数百万站点、数十亿请求和每次新部署。思路是,当网络观察到一个 URL 模式中,连续响应共享大部分内容但哈希不同,它就有强信号表明该资源是有版本的、是 delta compression 的候选。它把前一版本存为 dictionary,并对后续版本做压缩。客户无需配置,无需维护。

这是个简单的想法,但确实困难。安全地生成不泄露隐私数据的 dictionary,以及识别 dictionary 能带来最大收益的流量,都是真实的工程问题。但 Cloudflare 拥有合适的拼图块:我们能看到整个网络的流量模式;我们已经管理 dictionary 需要驻留的缓存层;我们到客户端的 RUM beacon 能为我们提供验证回路,在我们承诺提供 dictionary 之前确认它确实改善了压缩。流量可见性、edge 存储与合成测试的组合,使自动生成成为可行,尽管还有许多细节要厘清。

phase 3 的性能与带宽收益是我们动机的核心。这才是让 shared dictionaries 对每个使用 Cloudflare 的人 —— 包括从未有工程时间手动实现自定义 dictionary 的数百万 zone —— 都触手可及的关键。

更宏大的图景

在 web 历史的大部分时间里,压缩是无状态的。每次响应都被压缩,仿佛客户端从未见过任何东西。Shared dictionaries 改变了这一点:它们让压缩有了记忆。

这件事比五年前更重要。Agentic 编码工具压缩了部署间的间隔,同时驱动消费它们的流量份额不断增长。虽然今天 AI 工具能产出庞大的 diff,但 agents 在获得更多上下文,代码改动也变得外科手术般精准。这与更频繁的发布和更多自动化客户端结合,意味着每次请求中冗余字节更多。Delta compression 同时帮到等式两边:减少每次传输的字节数,以及需要发生的传输次数。

Shared Dictionaries 花了几十年才被标准化。Cloudflare 正在帮助构建基础设施,让它对每个接触你站点的客户端 —— 不论是人类还是非人 —— 都可用。Phase 1 beta 在 4 月 30 日 开放,我们期待你来试。

_____

1Bots = ~31.3% 所有 HTTP 请求。AI = ~29-30% 所有 Bot 流量(2026 年 3 月)。