优化基于文本的资源的编码和传输大小

除了消除不必要的资源下载外,您可以做的提高页面加载速度的最佳方法是通过优化和压缩剩余资源来最大限度地减少整体下载大小。

数据压缩 101

在您设置好网站以避免下载任何未使用的资源后,下一步是压缩浏览器必须下载的任何剩余的合格资源。根据资源类型(文本、图像、字体等),有许多不同的技术可供选择:可以在 Web 服务器上启用的通用工具、针对特定内容类型的预处理优化以及需要开发人员输入的特定于资源的优化。

要获得最佳性能,需要结合以下所有技术

  • 压缩是使用更少的位对信息进行编码的过程。
  • 消除不必要的数据始终会产生最佳结果。
  • 有许多不同的压缩技术和算法。
  • 您将需要多种技术来实现最佳压缩。

减小数据大小的过程称为数据压缩。许多人贡献了算法、技术和优化,以提高压缩率、压缩速度以及各种压缩算法所需的内存。

对数据压缩的全面讨论远远超出了本指南的范围。但是,重要的是要从高层次上理解压缩的工作原理,以及您可以用来减小页面所需的各种资源大小的技术。

为了说明这些技术的核心原则,请考虑优化一个简单的文本消息格式的过程,该格式是专门为此示例发明的

# Below is a secret message, which consists of a set of headers in
# key-value format followed by a newline and the encrypted message.
format: secret-cipher
date: 08/25/16
AAAZZBBBBEEEMMM EEETTTAAA
  1. 消息可能包含任意注释(有时称为注释),这些注释由“#”前缀指示。注释不影响消息的含义或其行为。
  2. 消息可能包含标头,标头是键值对(在前面的示例中用 ":" 分隔),出现在消息的开头。
  3. 消息携带文本有效负载。

可以做些什么来减小之前消息的大小(从 200 个字符开始)?

  1. 注释很有趣,但不影响消息的含义。传输消息时将其删除。
  2. 有一些很好的技术可以有效地编码标头。例如,如果您知道所有消息都有“format”和“date”,您可以将它们转换为短整数 ID 并仅发送这些 ID。但是,这可能不是真的,所以最好暂时不要管它。
  3. 有效负载仅是文本。虽然我们不知道它的内容到底是什么(显然,它使用的是 "secret-cipher"),但仅查看文本就可以看出其中有很多冗余。也许您可以只计算重复字母的数量并更有效地编码它们,而不是发送重复字母。例如,"AAA" 变为 "3A",表示三个 A 的序列。

结合这些技术会产生以下结果

format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A

新消息的长度为 56 个字符,这意味着您已将原始消息压缩了 72%。这是一个显着的减少!

这是一个玩具示例,说明压缩算法如何在减少基于文本的资源的传输大小方面有效。实际上,压缩算法比前面的示例所示的要复杂得多,并且在 Web 上,压缩算法可以用于显着减少资源的下载时间。通过对基于文本的资源应用压缩,网页可以花费更少的时间加载资源,从而使用户可以比不压缩更快地看到这些资源的效果。

缩小:预处理和特定于上下文的优化

此处讨论的第一种技术是缩小。虽然缩小严格来说不是压缩算法,但它是一种删除源代码中使用的不必要和冗余字符的方法,使资源对人类更具可读性。但是,这种可读性对于在生产网站上维护该源代码的功能不是必需的,并且可能会延迟 Web 上资源的加载。

缩小是一种特定于内容的优化类型,可以显着减小交付资源的大小,并且这些优化最好在您的构建和部署过程中应用。例如,捆绑器是一种常用的软件类型,可以在将新生产代码部署到网站之前自动缩小资源。

压缩冗余或不必要数据的最佳方法是消除它。但是,您不能只是删除任意数据。然而,在某些上下文中,我们对数据格式及其属性具有特定于内容的知识,因此可以在不影响其真实含义或功能的情况下显着减小有效负载的大小。

<html>
  <head>
    <style>
      /* awesome-container is only used on the landing page */
      .awesome-container {
        font-size: 120%;
      }

      .awesome-container {
        width: 50%;
      }
    </style>
  </head>
  <body>
    <!-- awesome container content: START -->
    <div>
      This is my awesome container, and it is <em>so</em> awesome.
    </div>
    <!-- awesome container content: END -->
    <script>
      awesomeAnalytics(); // Beacon conversion metrics
    </script>
  </body>
</html>

考虑之前的 HTML 代码段及其包含的三种不同内容类型

  1. HTML 标记。
  2. 用于自定义页面演示文稿的 CSS。
  3. 用于增强交互和其他高级页面功能的 JavaScript。

但是,仍然存在一个问题,“如何减小此页面的大小?”

  • 代码注释是开发人员最好的朋友,但浏览器不需要它们!删除 CSS (/* ... */)、HTML (<!-- ... -->) 和 JavaScript (// ...) 注释会减少页面及其子资源的总传输大小。
  • “智能”CSS 压缩器可能会注意到我们正在使用一种效率低下的方式来定义 .awesome-container 的规则,并将两个声明折叠为一个,而不会影响任何其他样式,从而节省更多字节。在大量 CSS 规则中,删除这种冗余可以累积起来,但这可能不是可以积极应用的东西,因为选择器通常必须在不同的上下文中重复,例如在媒体查询中。
  • 空格和制表符是 HTML、CSS 和 JavaScript 中的开发人员便利。额外的压缩器可以删除所有制表符和空格。与其他重复数据删除技术不同,这种优化可以相当积极地应用,只要这些空格或制表符对于页面的演示文稿不是必需的即可——例如,您需要保留 HTML 文档文本运行中的空格,因为它们确保了用户实际看到的内容的可读性。
<html><head><style>.awesome-container{font-size:120%;width:50%}</style></head><body><div>This is my awesome container, and it is <em>so</em> awesome.</div><script>awesomeAnalytics()</script></body></html>

应用之前的步骤后,页面从 516 个字符减少到 204 个字符,这表示节省了大约 60%。当然,它不是很可读,但它不需要可读才能使用。现代开发实践还允许您将格式良好且可读的源代码版本与您交付到生产环境的良好优化代码分开。结合 源映射(它提供了已转换的生产代码的可读表示形式,让您可以更轻松地排除生产环境中的错误),您可以同时拥有良好的开发人员体验,同时为了用户体验而优化性能。

前面的示例说明了一个重要的观点:通用压缩器(例如,旨在压缩任意文本的压缩器)可以在压缩前面示例中的页面方面做得很好,但它永远不会知道要删除注释、折叠 CSS 规则或数十个其他特定于内容的优化。这就是为什么预处理、缩小和其他上下文感知优化很重要。

同样,上面描述的技术可以扩展到基于文本的资源之外。图像、视频和其他内容类型都包含其自身的元数据和各种有效负载。例如,每当您用相机拍照时,其文件通常会嵌入许多额外信息:相机设置、位置等等。根据您的应用程序,此数据可能至关重要(例如,照片共享网站),或者可能完全无用。您应该考虑是否值得删除它。在实践中,此元数据对于每个图像最多可以增加数十千字节。

简而言之,作为优化资产效率的第一步,建立不同内容类型的清单,并考虑您可以应用哪些特定于内容的优化来减小其大小。然后,在您弄清楚它们是什么之后,通过将这些优化添加到您的构建和发布步骤来自动化这些优化,以确保每次发布到生产环境时都一致地应用优化。

使用压缩算法进行文本压缩

减小基于文本的资源大小的下一步是对其应用压缩算法。这更进一步,在将基于文本的有效负载发送给用户之前,积极搜索其中可重复的模式,并在它们到达用户的浏览器后对其进行解压缩。结果是这些资源的进一步显着减少,以及随后的更快的下载时间。

  • gzip 和 Brotli 是常用的压缩算法,在基于文本的资源(CSS、JavaScript、HTML)上表现最佳。
  • 所有现代浏览器都支持 gzip 和 Brotli 压缩,并且将在 Accept-Encoding HTTP 请求标头中声明对两者的支持。
  • 必须配置您的服务器以启用压缩。Web 服务器软件通常默认启用模块来压缩基于文本的资源。
  • gzip 和 Brotli 都可以通过调整压缩级别来微调以提高压缩率。对于 gzip,压缩设置范围为 1 到 9,其中 9 为最佳。对于 Brotli,此范围为 0 到 11,其中 11 为最佳。但是,更高的压缩设置需要更多时间。对于 动态压缩的资源(即在请求时),范围中间的设置往往在压缩率和速度之间提供最佳折衷方案。但是,静态压缩是可能的,即在响应预先压缩时,因此可以使用每种压缩算法可用的最积极的压缩设置。
  • 内容分发网络 (CDN) 通常提供对合格资源的自动压缩。CDN 还可以为您管理动态和静态压缩,从而减少您需要担心的压缩方面。

gzipBrotli 是常见的压缩器,可以应用于任何字节流。在后台,它们会记住文件之前检查过的一些内容,然后尝试以有效的方式查找和替换重复的数据片段。

在实践中,gzip 和 Brotli 在基于文本的内容上表现最佳,对于较大的文件,通常可以实现高达 70-90% 的压缩率。但是,对已使用替代算法(例如大多数使用无损或有损压缩技术的图像格式)压缩的资产运行这些算法几乎没有改进。

所有现代浏览器都在 Accept-Encoding HTTP 请求标头中声明对 gzip 和 Brotli 的支持。但是,主机提供商有责任确保 Web 服务器已正确配置,以便在客户端请求压缩资源时提供该资源。

文件 算法 未压缩大小 压缩大小 压缩率
angular-1.8.3.js Brotli 1,346 KiB 256 KiB 81%
angular-1.8.3.js gzip 1,346 KiB 329 KiB 76%
angular-1.8.3.min.js Brotli 173 KiB 53 KiB 69%
angular-1.8.3.min.js gzip 173 KiB 60 KiB 65%
jquery-3.7.1.js Brotli 302 KiB 69 KiB 77%
jquery-3.7.1.js gzip 302 KiB 83 KiB 73%
jquery-3.7.1.min.js Brotli 85 KiB 27 KiB 68%
jquery-3.7.1.min.js gzip 85 KiB 30 KiB 65%
lodash-4.17.21.js Brotli 531 KiB 73 KiB 86%
lodash-4.17.21.js gzip 531 KiB 94 KiB 82%
lodash-4.17.21.min.js Brotli 71 KiB 23 KiB 68%
lodash-4.17.21.min.js gzip 71 KiB 25 KiB 65%

上表显示了 Brotli 和 gzip 压缩可以为一些知名的 JavaScript 库提供的节省。根据文件和算法,节省范围为 65% 到 86%。作为参考,Brotli 和 gzip 都对每个文件应用了最大压缩级别。在任何可能的情况下,首选 Brotli 而不是 gzip。

启用压缩是实现的最简单和最有效的优化之一。如果您的网站没有利用它,那么您就错过了一个提高用户性能的绝佳机会。幸运的是,许多 Web 服务器提供默认配置,可以启用此重要优化,尤其是 CDN 在以平衡压缩速度和比率的方式实现它方面非常有效。

查看压缩效果的一种快速方法是打开 Chrome DevTools,打开网络面板,加载您选择的页面,并观察网络面板的最底部。

DevTools readout of actual versus transfer size.
Chrome DevTools 的网络面板中可视化的所有页面资源的传输大小(即压缩后的大小)与其实际大小的表示形式。

与上图类似,您应该看到以下各项的细分

  • 请求数,即页面加载的资源数。
  • 所有请求的传输大小。这反映了应用于页面任何资源的压缩的有效性。
  • 所有请求的资源大小。这反映了页面资源解压缩后的大小。

对 Core Web Vitals 的影响

除非有反映这些改进的指标,否则无法衡量性能改进。Core Web Vitals 计划的存在是为了创建和提高对反映实际用户体验的指标的认识。这与诸如简单页面加载时间之类的指标形成对比,这些指标不能清楚地转化为用户体验质量。

当您将本指南中概述的优化应用于您网站上的资源时,对 Core Web Vitals 的影响可能会因优化的资源和所涉及的指标而异。但是,以下是一些应用这些优化可以改善您网站的 Core Web Vitals 的实例

  • 缩小和压缩的 HTML 资源可以改善 HTML 的加载、其子资源的可发现性,从而改善它们的加载。这可能对页面的最大内容渲染时间 (LCP) 有益。虽然可以使用诸如 rel="preload" 之类的资源提示来影响资源的可发现性,但使用过多的资源提示可能会导致带宽争用问题。通过确保导航请求的 HTML 响应已压缩,预加载扫描器可以尽快发现其中的资源。
  • 通过使用压缩,还可以更快地加载一些 LCP 候选元素。例如,作为 LCP 候选元素的 SVG 图像可以通过基于文本的压缩来减少其资源加载持续时间。这与您对其他图像类型(这些图像类型本质上是通过其他压缩方法压缩的)进行的优化不同,例如 JPEG 图像如何使用有损压缩。
  • 此外,文本节点也可以是 LCP 候选元素。本指南中描述的技术如何取决于您是否在网页上的文本中使用 Web 字体。如果您正在使用 Web 字体,则适用Web 字体优化最佳实践。但是,如果您使用 Web 字体,而是使用无需承担任何资源加载持续时间即可显示的系统字体,则缩小和压缩 CSS 会减少此持续时间,这意味着潜在 LCP 文本节点的渲染可以更快地发生。

结论

您如何优化基于文本的资产的编码和传输是一种基准性能概念,但它具有很大的影响。请确保您正在尽一切努力确保符合缩小和压缩条件的资源从这些优化中受益。

更重要的是,请确保这些过程是自动化的。对于缩小,请使用捆绑器将缩小应用于符合条件的资源。确保您的 Web 服务器配置支持压缩,但更重要的是,使用最有效的可用压缩。为了使此过程尽可能简单,请使用 CDN 为您自动化压缩,因为它们不仅可以为您压缩资源,而且还可以非常快速地执行此操作。

通过将这些基准性能概念融入您网站的架构中,您可以确保您的性能优化工作有一个良好的基础,并且后续的优化可以建立在良好的基准实践的坚实基础上。