我在 CDN 规模下如何使用 Brotli 获取更小的 CSS 和 JavaScript 文件

Avatar of Hamid Sarfraz
Hamid Sarfraz

DigitalOcean 为您旅程的每个阶段提供云产品。从 免费赠送 200 美元的信贷 开始!

HBO 的情景喜剧《硅谷》滑稽地讲述了 Pied Piper 的故事,他们是一群梦想通过创建强大的压缩算法来改变现状的开发人员,从而让高质量的流媒体和文件存储成为过去。

在剧中,谷歌由虚构的公司 Hooli 代替,Hooli 觊觎着 Pied Piper 的知识产权。有趣的是,虽然远非初创公司,但谷歌在现实生活中确实拥有一个名为 Brotli 的强大压缩引擎。

本文讲述了我使用 Brotli 在生产规模上的经验。尽管在更高压缩级别上,即时压缩非常昂贵且实际上不可行,但 Brotli 实际上非常经济,并在许多方面节省了成本,尤其是在与 gzip 或更低 Brotli 压缩级别(我们稍后将讨论)相比时。

Brotli 的起源...

2015 年,谷歌 发布了一篇博文 宣布 Brotli 并发布了其 GitHub 上的源代码。两位创建 Brotli 的开发者也在两年前创建了谷歌的 Zopfli 压缩。但是,Zopfli 利用了现有的压缩技术,而 Brotli 是从头开始编写的,并且完全专注于文本压缩,以使静态 Web 资源(如 HTML、CSS、JavaScript 甚至 Web 字体)受益。

当时,我是一名自由网站性能顾问。我对 Brotli 承诺的比 Zopfli 提高 20-26% 的性能感到非常兴奋。与 zlib 的标准实现相比,Zopfli 本身是 deflate 压缩器 的密集实现,因此高达 26% 的说法非常令人印象深刻。什么是 zlib? 它本质上与 gzip 相同。

因此,我们看到的是下一代 Zopfli,它是 zlib 的分支,zlib 本质上与 gzip 相同。

令人失望的故事

主要 CDN 玩家花了几个月时间才支持 Brotli,但与此同时,它在工具、服务、浏览器和服务器中得到了广泛的采用。然而,Brotli 承诺的 26% 密集压缩从未在生产中反映出来。一些 CDN 在内部设置了较低的压缩级别 而另一些 CDN 在源头上支持 Brotli,以便只有在源头上 手动启用 的情况下才支持 Brotli。

服务器对 Brotli 的支持相当不错,但是为了达到高压缩级别,需要滚动 自己的预压缩代码 或使用服务器模块为你完成此操作,这并不总是可行的,尤其是在共享主机服务的情况下。

这对我来说真的很令人失望。我想为我的客户网站压缩每一个可能的字节,以使其更快,但使用预压缩并允许客户按需更新文件并不总是容易。

亲力亲为

我开始为我的客户构建自己的性能优化服务。

我有一些 技巧 可以显着提高网站速度。该服务将所有优化分为三组,分别包含几个“内容”、“交付”和“缓存”优化。我将 Brotli 纳入服务内容优化部分,用于可压缩资源。

与其他压缩格式一样,Brotli 也具有不同的功能级别。Brotli 的最大级别与电影《这是 Spinal Tap》中吉他放大器的最大音量完全一样:它高达 11。

Brotli:11 或 Brotli 压缩级别 11 可以显着减少可压缩文件的尺寸,但代价不菲:它非常慢,无法像 gzip 那样实现按需压缩。它在 CPU 时间方面要贵得多。

在我的基准测试中,Brotli:11 压缩一个单独的最小化 jQuery 文件需要数百毫秒。因此,为我的客户提供 Brotli:11 的唯一方法是将其用于预压缩,这让我必须找到一种在服务器级别缓存文件的方法。幸运的是,我们已经实现了这一点。唯一的问题是担心 Brotli 会耗尽我们所有处理资源。

也许这就是 Pied Piper 必须不断调整其服务器以获得更多电力的原因。

我抛开恐惧,将 Brotli:11 构建为可配置的服务器选项。这样,客户可以决定启用它是否值得计算成本。

它很慢,但会逐渐产生回报

在我的客户服务中,除了其他几个优化外,还提供 地理内容交付;换句话说,它内置了 CDN。

在我亲力亲为时尝试的几个技巧中,一个技巧是将公共 CDN(或开源 CDN)和私有 CDN 结合到单个主机上,以便网站可以享受公共资源的共享浏览器缓存带来的好处,而无需为该公共主机产生单独的 DNS 查找和连接成本。我想要避免这种额外的连接成本,因为它会对 移动用户产生重大影响。此外,将越来越多的资源组合到单个主机上可以帮助充分利用 HTTP/2 功能,例如 多路复用

我启用了 公共 CDN,并为所有可压缩资源(包括 CSS、JavaScript、SVG 和 TTF 以及其他类型的文件)开启了 Brotli:11 预压缩。压缩开销确实在每个资源的首次请求中有所增加,但之后一切似乎都运行顺利。Brotli 拥有 超过 90% 的浏览器支持率,几乎所有到达我服务的请求现在都使用 Brotli。

我很高兴。客户也很高兴。但我没有数据。我开始分析启用这种高密度压缩对公共资源的影响。为此,我记录了 几个流行库的文件传输大小,包括 jQuery、Bootstrap、React 和其他框架,这些框架使用了其他 CDN 实现的常见压缩方法,发现 Brotli:11 压缩与其他压缩格式相比节省了约 21%。

需要注意的是,我比较的一些其他公共 CDN 已经使用 Brotli,但在较低的压缩级别上。因此,21% 的额外压缩对我来说真的很令人满意。这个数字是基于非常小的库子集,但并没有偏离太大,因为我在我测试的所有网站上都看到了这种程度的提升。

以下是节省情况的图形表示。

Vertical bar chart. Compares jQuery, Bootstrap, D3.js, Ant Design, Senamtic UI, Font Awesome, React, Three.js, Bulma and Vue before and after Brotli compression. Brotli compression is always smaller.

您可以在下面看到原始数据。注意,CSS 的节省比 JavaScript 的节省要大得多。

原始常见压缩平均值 (A)Brotli:11 (B)(A) / (B) – 1
Ant Design1,938.99 KB438.24 KB362.82 KB20.79%
Bootstrap152.11 KB24.20 KB17.30 KB39.88%
Bulma186.13 KB23.40 KB19.30 KB21.24%
D3.js236.82 KB74.51 KB65.75 KB13.32%
Font Awesome1,104.04 KB422.56 KB331.12 KB27.62%
jQuery86.08 KB30.31 KB27.65 KB9.62%
React105.47 KB33.33 KB30.28 KB10.07%
Semantic UI613.78 KB91.93 KB78.25 KB17.48%
three.js562.75 KB134.01 KB114.44 KB17.10%
Vue.js91.48 KB33.17 KB30.58 KB8.47%

结果很棒,正如我所料。那么在规模上使用 Brotli:11 的整体影响如何呢?事实证明,对所有公共资源使用 Brotli:11 会降低整体成本。

  • 较小的文件尺寸预计会带来更低的 TLS 开销。也就是说,它不容易测量,对于我的服务来说也不那么重要,因为现代 CPU 在加密方面非常快。尽管如此,我相信由于较小的文件加密速度更快,因此对于每个请求都有一些微小的重复节省。
  • 它降低了带宽成本。我得到的 21% 的整体节省就是一个很好的例子。而且,请记住,节省不是一次性的事情。每个请求都算作成本,因此 21% 的节省会一次又一次地重复出现,从而为带宽成本创造了滚雪球式的节省。
  • 我们只在边缘服务器上将热文件缓存到内存中。由于浏览器对 Brotli 的广泛支持,这些热文件大多由 Brotli 编码,它们的小尺寸使我们能够将更多文件放入可用内存中。
  • 访问者(尤其是移动设备用户)享受减少的数据传输。这将带来 更少的电池使用量以及数据费用节省。这对我们客户的用户来说是一个巨大的胜利!

这太棒了。我们每次请求节省的成本并不显著,但考虑到公共资源的缓存命中率几乎为零,我们可以轻松地在接下来的数百次请求中摊销压缩的初始高成本。之后,我们将看到降低开销带来的长期效益。

这并非全部

在我们作为性能优化服务的一部分引入的公共和私有 CDN 的组合中,我们希望确保客户可以为私有 CDN 上经常随时间变化的资源(如自定义 CSS 和 JavaScript)设置较低的压缩级别,并自动切换到公共 CDN 上的开源资源,这些资源变化频率较低,并且预先配置了 Brotli:11。这样,我们的客户仍然可以在变化频率较低的资源上获得高压缩率,同时仍然享受可压缩资源的即时清除和更新带来的良好压缩率。

所有这些都是通过我们的集成工具平滑且无缝地完成的。这种方法对客户的额外好处是,公共 CDN 上的带宽完全免费,并且具有前所未有的性能水平。

亲身体验!

在一个常见的网站上测试,使用激进的压缩可以轻松地 **从页面加载中减少大约 50 KB**。如果你想玩转免费的公共 CDN 并享受更小的 CSS 和 JavaScript,欢迎使用我们的 PageCDN 服务。以下是一些最常用的库供你使用

<!-- jQuery 3.5.0 -->
<script src="https://pagecdn.io/lib/jquery/3.5.0/jquery.min.js" crossorigin="anonymous" ></script>


<!-- FontAwesome 5.13.0 -->
<link href="https://pagecdn.io/lib/font-awesome/5.13.0/css/all.min.css" rel="stylesheet" crossorigin="anonymous" >


<!-- Ionicons 4.6.3 -->
<link href="https://pagecdn.io/lib/ionicons/4.6.3/css/ionicons.min.css" rel="stylesheet" crossorigin="anonymous" >


<!-- Bootstrap 4.4.1 -->
<link href="https://pagecdn.io/lib/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous" >


<!-- React 16.13.1 -->
<script src="https://pagecdn.io/lib/react/16.13.1/umd/react.production.min.js" crossorigin="anonymous" ></script>


<!-- Vue 2.6.11 -->
<script src="https://pagecdn.io/lib/vue/2.6.11/vue.min.js" crossorigin="anonymous" ></script>

我们的 PHP 库 会在必要时自动在私有 CDN 和公共 CDN 之间切换。我们的 WordPress 插件 实现了相同的特性,该插件会自动通过公共 CDN 加载公共资源。这两种工具都允许完全访问免费的公共 CDN。JavaScript、Python 和 Ruby 的库尚不可用。如果你为我们的公共 CDN 贡献任何此类库,我将很乐意将其列在我们的文档中。

此外,你可以使用我们的搜索工具,通过提供网站上资源的 URL 来立即在公共 CDN 上找到相应的资源。如果这些工具都不适合你,那么你可以查看相关的库页面,并选择你想要的 URL。

展望未来

我们最初只托管最流行的库,以防止恶意软件传播。然而,情况正在迅速变化,我们根据用户的建议添加新的库。欢迎你推荐你喜欢的库。如果你仍然想链接到公共或私有 Github 存储库(尚未在我们的公共 CDN 上提供),你可以使用我们的私有 CDN 连接到存储库,并将所有新版本导入到 Github 上,然后在交付之前应用自己的激进优化。

你的想法是什么?

我们在这里讨论的所有内容都完全基于我在 CDN 规模上使用 Brotli 压缩的个人经验。它恰好也是我对公共 CDN 的介绍。我们仍然是一个小型服务,我们的客户网站只有数百个。尽管如此,在这个规模上,激进的压缩似乎是有效的。

我已经为我的客户实现了高质量的结果,现在你也可以将这项免费服务用于你的网站。如果你喜欢它,请在我的 电子邮件 上留下反馈,并向其他人推荐它。