现实世界中的Brotli效率

开发快速网站的最基本规则之一是优化其资源。如果我们正在谈论文本资源-涉及用HTML,CSS和JavaScript编写的代码,则意味着我们正在谈论数据压缩。 用于压缩Web上文本资源的事实上的标准是Gzip方法。即,使用Gzip压缩站点下载期间获得的大约80%的压缩资源。为了压缩其余20%的资源,使用了一种更新得多的算法-Brotli。





当然,当浏览器收到对网站请求的答复时,进入浏览器的这100%压缩资源并不绝对包含所有资源。仍然有许多资源可以压缩,也可以压缩。但是这些资源仍未压缩。有关压缩的更详细指标,可以在Web年鉴资源的“ 压缩”部分中找到

gzip压缩方法非常有效。莎士比亚的所有纯文本著作都需要5.3 MB。在进行Gzip压缩(压缩级别6)之后,它们仅占用1.9 MB。这意味着存储该数据的文件大小减少了2.8倍。同时,在压缩过程中数据不会丢失。大!

更好的是,文件中重复行的存在会影响Gzip压缩的程度。文本中重复次数越多,压缩效率越高。这对于Web来说非常好,因为用HTML,CSS和JS编写的代码具有统一的语法并包含许多重复。

但是,尽管Gzip是一种非常有效的压缩方法,但它也相当古老。它于1992年出现(这当然有助于解释其普遍性)。 21年后的2013年,Google发布了Brotli,这是一种新算法,与Gzip方法相比,它的压缩水平更高。使用Brotli将莎士比亚5.2 MB的相同作品压缩为1.7 MB(压缩级别为6)。这已经意味着文件大小减小了3.1倍。这甚至比使用Gzip更好。

使用工具评估使用Gzip和Brotli的数据压缩级别,您可能会发现,压缩某些数据时,Brotli比Gzip效率更高。例如,与使用最大压缩级别(9)的Gzip相比,使用最大压缩级别(11)的Brotli进行压缩时,ReactDOM数据要小27%。

这是处理ReactDOM时Brotli压缩与Gzip压缩的比较。

压缩等级大小(以字节为单位)压缩效率(与未压缩数据相比)比Gzip改善的百分比
1个434562.733%
2398982.97十一%
3394163.08十五%
4384883.08十五%
5363233.27十九%
6360483.29二十%
7358043.31二十%
8357093.3221%
9356593.3321%
10335903.5325%
十一330363.5927%

如您所见,在所有压缩级别,Brotli都会绕过Gzip。在Brotli提供的最大压缩级别下,它的效率比Gzip高出27%。

而且,根据个人观察,我注意到我的一位客户从Gzip转移到Brotli导致文件大小平均减少了31%。

因此,在过去的几年中,我与其他性能专家一起一直在鼓励客户从Gzip转到Brotli。

我会说几句关于浏览器对Gzip和Brotli的支持。 Gzip如此广泛,以至于CanIUse甚至不显示带有支持信息的表。它说:“几乎所有浏览器都支持此HTTP标头(从IE6 +,Firefox 2 +,Chrome 1+等开始)。” Brotli在撰写本文时,获得了非常令人愉快的支持。为93.17%。这是非常非常的!因此,如果您的站点至少具有一定的规模,则可能不希望将未压缩的资源返还给超过6%的用户。但是使用Brotli,您将不会损失任何东西。客户使用支持新算法的渐进模型,因此无法接受Brotli资源的用户将仅使用Gzip形式的后备选项。我们将在下面讨论更多。

通常,特别是如果使用CDN,打开Brotli只需几秒钟。至少Cloudflare就是这种情况,Cloudflare是我用于CSS Wizardry网站的服务。但是,如果我们谈论最近几年,我的许多客户都不是那么成功。其中有些支持自己的基础结构,实践表明,安装和部署Brotli并非如此简单。有些使用CDN服务,在支持新算法的容易访问的功能上没有区别。

在那些我们无法切换到Brotli的情况下,我们总是有一个未解决的问题:“如果...怎么办”。结果,我最终决定用数字武装自己,并回答如何使站点过渡到Brotli的问题。

少不一定意味着更快。


但是,通常“更少”意味着“更快”。通常,如果减小文件大小,它将从服务器更快地传输到客户端。但是,如果您将文件缩小20%,这并不意味着它将更快地到达20%。这里的要点是文件大小只是Web性能的一方面。而且,无论文件大小如何,传递给浏览器的资源都与许多其他因素和许多系统限制(网络延迟,数据包丢失等)相关联。换句话说,节省文件大小有助于传输与以前相同的数据,发送较少的数据包,但是服务器和客户端之间的数据传输受到网络延迟的限制,结果,到达客户端的数据包较小的速度不会改变。

TCP,数据包,往返延迟


如果考虑将文件从服务器传输到客户端非常简单,我们将不得不考虑一下TCP协议。当我们从服务器收到文件时,它不会一go而就。 TCP协议可将文件分成称为数据包的段,TCP协议可基于HTTP协议工作。这些数据包按顺序发送到客户端。客户端在开始下一个系列的传输之前,确认该系列中每个数据包的接收。直到客户端收集了所有必要的程序包,直到服务器上没有未发送的程序包,并且直到客户端可以将程序包收集到可以识别为文件的文件中为止。为了使数据包序列传输会话成功完成,服务器必须将它们发送给客户端,并且客户端必须确认其接收。时间,接收数据和接收确认消息所需的数据量称为往返时间(RTT)。

每个新的TCP连接都无法知道可用带宽是多少,以及连接的可靠性如何(即,丢包的级别是多少)。如果服务器尝试通过支持每秒一兆位数据传输速率的连接发送兆字节的数据,则这种传输将使连接不堪重负,并导致通信通道过载。反之亦然-如果服务器尝试通过非常快速的连接传输少量数据,则该连接将被低效率地使用,它将处于空闲状态。

为了解决这个难题,TCP使用了一种称为慢启动的机制。这是过载窗口管理策略的一部分。每个新的TCP连接都受到以下限制:在第一个数据包序列中只能发送10个数据包(10个数据包-初始拥塞窗口的大小)。十个TCP段大约为14 KB数据。如果客户端成功接收了这些软件包,则第二个系列将已经包含20个软件包,然后将有40、80、160等。数据包在序列中的增长将持续到发生以下事件之一为止:

  1. 系统将面临数据包丢失。此时,服务器将按照以下顺序减少数据包数量,将先前的数据包数量除以2,然后尝试再次传输数据。
  2. 我们已达到可用带宽的极限,可以满负荷使用。

这种简单而优雅的策略可让您在谨慎和乐观的边缘保持平衡。它适用于Web应用程序建立的每个新的TCP连接。

简而言之,新TCP连接的拥塞窗口的初始大小仅为14 Kb。约占未压缩ReactDOM数据的11.8%。使用Gzip压缩的数据的36.94%,或使用Brotli压缩的数据的42.38%(处于最大压缩级别)。

然后我们放慢速度。从11.8%到36.94%的过渡已经是非常明显的进步!但是从36.94%到42.38%的过渡-距离如此令人印象深刻。发生了什么?
数据会话号一个会话中传输的数据量,Kb累计传输数据量,KbReactDOM数据的传输顺序
1个1414
22842Gzip(37.904 Kb),Brotli(33.036 Kb)
35698
4112210未压缩的选件(118.656 Kb)
5224434

事实证明,使用Gzip压缩的数据和使用Brotli压缩的数据都在同一系列的数据包中传输。传输文件需要两个序列。如果在传输所有序列时RTT相当均匀,则意味着传输使用Gzip和Brotli压缩的数据需要花费相同的时间。另一方面,传输未压缩版本的数据需要四个系列的数据包,而不是两个。而且,尤其是在具有高网络延迟的连接上,这可能导致数据传输需要相当明显的时间。

我倾向于这样一个事实,即数据传输速度不仅取决于文件大小。它受TCP协议功能的影响。我们不仅需要使文件更小。我们需要使它们更小,使其具有一定的大小,以允许它们以更少的数据包序列进行传输。

从理论上讲,这意味着为了使Brotli算法比Gzip效率更高,它必须能够更加主动地压缩数据。这是必要的,因此与使用Gzip相比,数据可以更少的数据包序列进行传输。而且我不知道该算法将如何发展...

值得注意的是,上述模型已相当简化。还有许多其他因素需要考虑。例如-是新的还是已经打开的TCP连接?连接是否还用于其他用途?服务器流量优先级划分机制是否停止并开始数据传输? H / 2流是否具有带宽独占访问权?本节是更认真的研究。应该将其视为您自己研究的一个良好起点。但是,请考虑使用Wireshark之​​类的工具彻底分析数据,并阅读材料,材料提供了对“神奇的”前14 Kb的更深入的描述。

以上内容仅适用于全新的TCP连接。通过现有连接传输的文件将不会通过慢启动过程。这导致我们得出两个重要结论:

  1. 我认为不值得重复,但我会重复:静态资源需要托管。这是避免启动延迟的好方法,因为使用您自己的,已经“预热”的服务器意味着离开该服务器的数据包可以访问更宽的带宽。这个结论使我得出第二个结论。
  2. , , . , . .

, ,,
11414
22842
35698
4112210
5224434
6448882
78961778
817923570
935847154
10716814322
20734003214680050

在第10次数据传输会话结束时,在一个会话中传输的数据量为7168 Kb,而总共已传输14322 Kb数据。对于Internet上的常规工作(即,不用于查看《权力的游戏》),这已经绰绰有余了。实际上,通常会发生这样的情况:我们加载整个网页及其所有资源而没有达到带宽限制。换句话说,使用1 Gbit / s的光纤通信通道(即0.125 GB / s)将不会使正常浏览比使用较慢的连接快得多,因为该通道的大部分甚至都不会将会被使用。 

到第20次数据传输会话时,理论上我们将以一个数据包序列传输7.34 GB的数据。

那现实世界呢?


到目前为止,我们一直在进行理论上的考虑。由于我想了解Brotli对真实网站的影响,所以我开始研究此材料。

到目前为止,这里给出的数字表明缺乏压缩和使用Gzip之间的巨大差异,以及与Gzip相比,使用Brotli带来的收益是相当小的。这告诉我们,从缺乏压缩到使用Gzip的过渡将带来明显的改善,但是从Gzip到Brotli的过渡可能看起来不那么令人印象深刻。

我选择了几个站点作为示例,并遵循以下注意事项:

  • 该站点应该是相对知名的(最好使用可以与某些东西进行比较的站点)。
  • 该地点应适合进行测试。也就是说-它的大小应该合适(因此,分析其压缩材料会更有趣),同时,其主要不应包含未使用Gzip / Brotli压缩的材料-例如YouTube。
  • 并非馆藏中的所有网站都应该属于大型公司(值得分析一些,例如“常规”网站)。

鉴于这些要求,我选择了下面列出站点并开始测试。这是我选择的网站:


我不想使测试复杂化,因此决定采用以下指标:

  • 传输的数据量。
  • 首次合格油漆(FCP)时间。

在以下情况下对它们进行了分析:

  • 缺乏压缩。
  • 使用gzip。
  • 使用brotli。

FCP指标看起来非常接近现实世界,并且足以应用于任何站点,因为它使您可以评估人们对网站的需求-即这些站点的内容。此外,我之所以选择此指标,是因为有才华的Paul Calvano这样说:“经验告诉我,使用Brotli可以改善FCP,尤其是在关键CSS / JS资源很大的情况下” 。

测试中


我告诉你一个肮脏的秘密。 Web性能的许多研究(不是全部,而是很多)并不是基于对性能改进的研究,而是基于相反的结论-性能下降。例如,英国广播公司更容易断言:“由于每秒钟需要花费一秒钟的时间,他们就会失去10%的用户 ”,而不是知道发生了什么。放慢网站速度而不是提高网站速度要容易得多,您会因此而感到很多人干得这么好。

鉴于此,我没有尝试先下载使用Gzip的网站,然后离线使用Brotli以某种方式压缩其内容。相反,我发现了使用Brotli的网站,然后关闭了压缩功能。我从Brotli转到Gzip,然后从Gzip转到非压缩,以评估其在网站上的工作方式。

虽然我不能说能够连接到Linkedin服务器并断开Brotli的连接,但是我可以从不支持Brotli的浏览器简单地访问此站点。尽管我无法在Chrome中禁用Brotli支持,但是我可以从服务器中隐藏我的浏览器支持Brotli的事实。浏览器使用请求标头告知服务器它们支持哪种压缩算法content-encoding使用Webpagetest,我可以自己定制标题。所以,一切都非常简单!


WebPageTest的高级功能允许我们设置自定义请求标头。

这是我设置“自定义标头”字段的方法:

  • 完全关闭压缩:accept-encoding: randomstring
  • 禁用Brotli,但Gzip已支持:accept-encoding: gzip
  • 如果站点支持该压缩方法(并在浏览器支持的情况下),则要使用Brotli:该字段保持为空。

您可以通过检查content-encoding服务器响应中标头的存在(或不存在)来确定这是否按预期工作

结果


不出所料,从缺乏压缩到Gzip的过渡意味着重大改进,但是从Gzip到Brotli的过渡看起来并不那么令人印象深刻。我的实验原始数据可以在这里找到以下是我最感兴趣的发现:

  • Gzip : 73%.
  • FCP Gzip : 23.305%.
  • Brotli Gzip: 5.767%.
  • FCP Brotli Gzip: 3.462%.

这些都是中值。说到“材料尺寸”,我的意思是仅HTML,CSS和JavaScript。

由于使用了Gzip,与未压缩版本相比,文件大小减少了73%。使用Brotli只能将文件大小再减少5.7%。如果我们谈论FCP,则由于缺少Gzip,该指标比没有压缩的指标提高了23%,而Brotli仅对此增加了3.5%。

尽管这些结果似乎加强了理论,但仍有几种方法可以改善这些结果。首先是测试更多的站点,我想更详细地讨论两个站点。

自己的资源数据和来自外部来源的数据


在测试中,我在所有地方都关闭了Brotli,而不仅仅是关闭了存储站点数据的服务器。这意味着我不仅衡量了站点从使用Brotli所获得的收益,而且还就潜在性而言,衡量了Brotli从这些站点所使用的外部资源中获得的收益。仅当在调查站点的关键方式中使用第三方资源时,这才属于我们关注的范围,但这值得记住。

压缩等级


说到压缩,我们经常讨论使用最佳压缩应用方案获得的结果。即-使用Gzip时,我们要记住第9级压缩,而使用Brotli时,请注意第11级压缩。但是,不可能以最佳方式配置被调查服务器。例如,Apache使用6级gzip压缩,而NGINX仅使用第一种。

禁用Brotli意味着我们将切换到fallback选项,切换到Gzip,并且鉴于我测试站点的方式,我无法更改此类fallback配置或以某种方式对其进行操作。我之所以这样说是因为在打开Brotli时,测试中两个站点的材料实际上在增加大小。这向我表明,Gzip压缩级别比Brotli压缩级别提供了更强的压缩。

选择压缩级别是一个折衷方案。每个人都想问一下最高的压缩程度,并在此基础上考虑解决的问题。但是这种方法是不切实际的。事实是,服务器动态执行此压缩所需的额外时间很可能会抵消更高压缩级别的好处。为了解决此问题,您可以采取以下措施:

  1. 您可以使用务实的压缩级别,以在动态数据压缩期间提供速度和效率之间的适当平衡。
  2. 您可以将预压缩的静态资源上载到服务器,其压缩级别高于动态压缩所使用的级别。在这种情况下,要选择动态压缩级别,可以使用第一段中概述的想法。

摘要


一个人的印象是,明智地推理,可以认识到Brotli相对于Gzip的优势微不足道。

如果在CDN的控制面板中通过几次鼠标移动即可启用Brotli支持,则应立即拿起Brotli并将其打开。对这种压缩算法的支持足够广泛,不支持Brotli的浏览器很容易切换到备用机制,即使有一点改进也总比没有好。

如果可能,将以最大压缩级别预压缩的静态资源上载到服务器。对于动态压缩,请不要使用最高压缩级别,而请使用最低压缩级别。如果您使用NGINX,请确保您没有使用NGINX的标准第一级压缩。

但是,如果要使用Brotli,您可能需要数周的开发,测试和部署,而不必惊慌-只需确保对所有可压缩的内容都使用Gzip压缩(除文本资源外,还包括文件.ico和.ttf-当然,如果您的项目中使用了它们。

我想这篇文章的简短版本可能是这样的:如果您不应该或者不能启用Brotli,那么您并不会损失太多。

亲爱的读者们!您打算使用Brotli吗?


All Articles