过去十年间,网页每年都会变“重”6-9%,这是由网络变得更加框架驱动、交互性和多媒体丰富所推动的。这一趋势不会改变。真正改变的是这些页面被重建的频率以及请求它们的客户端数量。由于代理(agent)的存在,这两者都在急剧上升。
共享字典减少了从服务器到浏览器的资产传输,使得页面加载更快,网络传输更精简,尤其是对于回访用户或连接速度较慢的访客。每次部署后,浏览器不再重新下载整个 JavaScript 包,而是告诉服务器它已经缓存了什么,服务器只发送文件差异部分。
今天,我们很高兴向您预览我们对共享压缩字典的支持, 展示我们在早期测试中的发现,并透露您何时可以亲自试用测试版(提示:2026年4月30日!)。
问题:更多传输 = 更少缓存
代理爬虫、浏览器和其他工具反复访问端点,获取完整页面,通常只是为了提取一小部分信息。2026年3月,代理行为体占 Cloudflare 网络总请求量的不到10%,同比增长约60%。
每个传输的页面都比去年更重,并且被机器读取的频率比以往任何时候都高。但代理不仅消费网络,它们也在帮助构建网络。AI辅助开发意味着团队交付速度更快。 增加部署、实验和迭代的频率对产品速度有利,但对缓存却非常不利。
当代理推送一行修复时,打包器重新分块,文件名改变,地球上的每个用户都可能重新下载整个应用程序。不是因为代码有实质性的不同,而是因为浏览器/客户端无法知道具体改变了什么。它看到一个新的 URL,然后从零开始。传统压缩有助于减小每次下载的大小,但无法解决冗余问题。它不知道客户端已经缓存了文件的95%。因此,每次部署,每个用户,每个机器人,都会一遍又一遍地发送冗余字节。如果一天推送十个小改动,你实际上就放弃了缓存。在硬件迅速成为瓶颈的网络中,这浪费了带宽和 CPU。
为了应对更多请求访问更重且更频繁重新部署的页面,压缩必须变得更智能。
什么是共享字典?
压缩字典是服务器和客户端之间的共享参考,就像一张作弊纸条。服务器不是从头压缩响应,而是说“你已经知道文件的这一部分,因为你之前缓存过它”,只发送新的内容。客户端持有相同的参考,并在解压缩时用它来重建完整的响应。字典能引用的文件内容越多,传输给客户端的压缩输出就越小。
这种针对已知内容进行压缩的原理,正是现代压缩算法超越前代的关键。Brotli 内置了常见网页模式的字典,例如 HTML 属性和常用短语;Zstandard 专为自定义字典而设计:你可以向其提供代表性内容样本,它会为你所提供的内容类型生成优化字典。Gzip 两者都不具备;它必须在压缩过程中实时寻找模式来构建字典。这些“传统压缩”算法目前在 Cloudflare 上已经可用。
共享字典将这一原理更进一步:之前缓存的资源版本成为字典。还记得那个部署问题吗?团队发布了一行修复,每个用户都要重新下载整个包。使用共享字典,浏览器已经缓存了旧版本。服务器针对旧版本进行压缩,只发送差异部分。那个 500KB 的包,只改动了一行,在网络上传输时只有几 KB。假设每天有 10 万用户,每天部署 10 次,这意味着 500GB 的传输量与几百 MB 的差别。
增量压缩将浏览器已有的版本转化为字典。协议规定,当服务器首次提供资源时,它会附加一个 Use-As-Dictionary 响应头,告诉浏览器保留该文件,因为以后会用到。在下次请求该资源时,浏览器会发回一个 Available-Dictionary 头,告诉服务器:“这是我已有的内容。”然后服务器针对旧版本压缩新版本,只发送差异部分。不需要单独的字典文件。
这就是实际应用中的收益所在。版本化的 JS 包、CSS 文件、框架更新以及任何在版本之间增量变化的内容。浏览器已经缓存了 app.bundle.v1.js,开发者进行更新并部署了 app.bundle.v2.js。增量压缩只发送这些版本之间的差异。之后的每个版本也只是差异。版本三针对版本二压缩,版本 47 针对版本 46 压缩。节省不会重置,而是贯穿整个发布历史。
社区中也在积极讨论针对非静态内容的自定义和动态字典。这是未来的工作,但其影响重大。我们将在另一篇文章中讨论。
如果共享字典如此强大,为什么现在还没有人使用呢?
因为上一次尝试时,实现方案无法在开放的互联网上存活。
2008 年,Google 在 Chrome 中推出了 HTTP 共享字典压缩(SDCH)。它运行良好,一些早期采用者报告页面加载时间有两位数的提升。但 SDCH 积累问题的速度超过了任何人修复的速度。
最令人印象深刻的一类问题是压缩侧信道攻击(CRIME、BREACH)。研究人员表明,如果攻击者能够在与敏感内容(如会话 cookie、令牌等)一起压缩的内容中注入内容,压缩输出的大小可能会泄露关于秘密的信息。攻击者可以一次猜测一个字节,观察资源大小是否缩小,并重复直到提取出整个秘密。
但安全性并非唯一的问题,甚至也不是该方案未被采用的主要原因。SDCH 暴露了一些架构问题,例如违反了__同源策略__(讽刺的是,这也是它性能出色的部分原因)。其跨源字典模型__无法与 CORS 协调__,并且缺乏与 Cache API 等交互的规范。一段时间后,很明显采用时机尚未成熟,因此在 2017 年,Chrome(当时唯一支持的浏览器)__移除了__该功能。
让 Web 社区接过接力棒花了十年时间,但这是值得的。
现代标准 RFC 9842:压缩字典传输 弥补了使 SDCH 难以为继的关键设计缺陷。例如,它强制规定广告字典仅可用于同源响应,从而防止了许多可能导致侧信道压缩攻击的条件。
Chrome 和 Edge 已提供支持,Firefox 正在跟进。该标准正朝着广泛采用的方向发展,但完全的跨浏览器支持仍在追赶中。
RFC 缓解了安全问题,但字典传输的实现一直很复杂。源站可能需要生成字典、使用正确的标头提供字典、检查每个请求是否包含 Available-Dictionary
匹配、实时对响应进行增量压缩,并在客户端没有字典时优雅地回退。缓存也变得复杂。响应因编码和字典哈希而异,因此每个字典版本都会创建一个单独的缓存变体。在部署过程中,你会遇到使用旧字典的客户端、使用新字典的客户端以及没有字典的客户端。你的缓存会为每个客户端存储单独的副本。命中率下降,存储量上升,而字典本身必须在正常的 HTTP 缓存规则下保持新鲜。
这种复杂性是一个协调问题。而这正是边缘层所擅长的。CDN 已经位于每个请求的前端,已经管理压缩,并且已经处理缓存变体(敬请关注即将发布的公告博客)。
Cloudflare 如何构建共享字典支持
共享字典压缩涉及浏览器和源站之间堆栈的每一层。我们看到了客户的强烈兴趣:一些人已经构建了自己的实现,例如 RFC 作者 Patrick Meenan 的 dictionary-worker,它使用 WASM 编译的 Zstandard 在 Cloudflare Worker 内运行完整的字典生命周期(作为一个示例)。我们希望让每个人都能使用此功能,并尽可能简化实现。因此,我们分三个阶段在平台上推出该功能,从基础设施开始。
第一阶段:透传支持目前正在积极开发中。Cloudflare 转发共享字典所需的标头和编码,例如 Use-As-Dictionary
、Available-Dictionary
以及 dcb
和 dcz
内容编码,而不会剥离、修改或重新压缩它们。缓存键被扩展为根据 Available-Dictionary
和 Accept-Encoding
而变化,以便正确缓存字典压缩的响应。此阶段服务于在源站管理自己字典的客户。
我们计划在 2026 年 4 月 30 日 之前准备好第一阶段的公开测试版。要__使用__它,你需要位于启用了该功能的 Cloudflare 区域,并拥有一个源站,该源站使用正确的标头(Use-As-Dictionary)提供字典压缩的响应。
, Content-Encoding: dcb
或 dcz
, 根据 Accept-Encoding 变化
, Available-Dictionary
), 并且你的访问者需要使用支持字典传输的浏览器。目前,这意味着 Chrome 130+ 和 Edge 130+,Firefox 支持正在开发中。
请密切关注 changelog,了解何时可用以及更多使用文档。
我们已经开始在内部测试 passthrough。在一个受控测试中,我们依次部署了两个 JS 包。它们几乎相同,除了版本之间的一些本地化更改,代表同一 Web 应用的连续部署。我们运行了 200 次测试,访问位于加利福尼亚州圣何塞的 PoP,源站位于爱荷华州康瑟尔布拉夫斯,提供字典、JS 包和字典压缩包(注意 dcz 压缩包是预计算的)。对于每个请求,我们通过 curl 捕获 TTFB 和总下载时间。
未压缩时,资源大小为 272KB。Gzip 将其降至 92.2KB,减少了 66%。使用共享字典压缩(DCZ),以前一版本作为字典,同一资源降至 2.6KB。相比未压缩资源减少了 99%,仍比 gzip 小 97%。
在同一实验室测试中,我们测量了客户端的两个时间里程碑:首字节时间(TTFB)和完整下载完成时间。时间差异显著。在缓存未命中时,DCZ 的 TTFB 比 gzip 快约 60 毫秒。在缓存命中时,TTFB 差距缩小到可忽略的 10 毫秒。
下载完成才是关键。图表中的“传输”表示 curl 接收响应所花费的总时间减去 TTFB。在缓存未命中时,DCZ 响应的这个时间为 1 毫秒,而 gzip 为 161 毫秒(快 99.4%——主体基本上与头部同时到达)。在缓存命中时,1 毫秒对比 54 毫秒(快 98%)。版本之间的本地化更改已被字典捕获,这正是关键所在:对于大致相同应用的连续部署,共享字典消除了几乎所有冗余传输。
模拟最小 JS 包差异的初始实验室结果,实际结果将根据字典与资源之间的实际差异而变化。
阶段 2:在此阶段,Cloudflare 开始为你完成工作。你无需在源站处理字典头部、压缩和回退逻辑,而是通过规则告诉 Cloudflare 哪些资源应作为字典使用,我们为你管理其余部分。我们注入 Use-As-Dictionary 头部,存储字典字节,对新旧版本进行增量压缩,并为每个客户端提供正确的变体。你的源站提供正常响应。所有字典复杂性从你的基础设施转移到我们的。
为了演示这一点,我们构建了一个实时演示,展示实际效果。在此尝试:Can I Compress (with Dictionaries)?** **
该演示每分钟部署一个约94KB的新JavaScript包,旨在模拟典型的生产级单页应用包。部署之间的大部分代码是静态的;每次只有一小块配置发生变化,这也反映了真实世界的部署情况——大部分包是未改变的框架和库代码。当第一个版本加载时,Cloudflare的边缘将其存储为字典。当下一个部署到达时,浏览器发送其已有版本的哈希值,边缘节点针对该哈希值对新包进行增量压缩。结果:94KB压缩到大约450字节。相比gzip,这减少了99.5%,因为线路上传输的只有实际的差异部分。
演示站点包含操作指南,您可以通过curl、浏览器或您选择的工具自行验证压缩比。
第三阶段:字典代表网站自动生成。无需客户指定哪些资产用作字典,Cloudflare会自动识别它们。我们的网络已经看到流经它的每个资源的每个版本,这包括数百万个站点、数十亿次请求以及每一次新部署。其思路是,当网络观察到连续响应共享大部分内容的URL模式时,这强烈表明该资源是增量压缩的良好候选。如果安全可行,它将前一个版本存储为字典,并针对它压缩后续版本。无需客户配置。无需维护。
这是一个简单的想法,但实施起来确实困难。安全地生成避免泄露私有数据的字典,并识别哪些流量能从字典中获得最大收益,是真正的工程难题。但Cloudflare拥有合适的条件:我们看到整个网络的流量模式,我们已经管理着字典需要驻留的缓存层,并且我们的__RUM信标__到客户端可以帮助我们建立一个验证循环,在承诺提供字典之前确认它确实改善了压缩。流量可见性、边缘存储和合成测试的结合使得自动生成成为可能,尽管仍有许多问题需要解决。
第三阶段的性能和带宽优势是我们动力的关键。这使得使用Cloudflare的每个人都能访问共享字典,包括数百万个永远不会有工程时间手动实现自定义字典的站点。
在Web历史的大部分时间里,压缩是无状态的。每个响应都被压缩,仿佛客户端从未见过任何东西。共享字典改变了这一点:它们赋予了压缩记忆。
这现在比五年前更重要。智能编码工具正在压缩部署间隔,同时也在推动消耗这些部署的流量份额不断增长。虽然今天AI工具可以产生巨大的差异,但智能体正在获得更多上下文,并在代码更改中变得精准。再加上更频繁的发布和更多的自动化客户端,意味着每次请求都有更多冗余字节。增量压缩通过减少每次传输的字节数以及需要发生的传输次数,帮助解决了问题的两个方面。
共享字典花了几十年才实现标准化。Cloudflare 正在帮助构建基础设施,使其适用于访问您网站的每个客户端,无论是人类还是非人类。第一阶段测试版将于 4 月 30 日 开放,我们期待您的试用。
1机器人 = 约占所有 HTTP 请求的 ~31.3%。AI = 约占所有机器人流量的 ~29-30%(2026 年 3 月)。
