
性能的世界是美好而复杂的,充满各种变量和细节。研究表明,网站速度会直接影响企业的转化率和收入。近年来,行业更加注重性能可视性和 Web 速度的提升。从 2021 年 5 月开始,页面体验信号将被包含在谷歌搜索排行中。Wix 面临的独特挑战是要支持数百万个站点,其中一些站点是多年以前构建的,自诞生后就没有更新过。我们有各种工具和文章]可以帮助用户分析和改善他们站点 Web 服务的性能。
Wix 是一个受管理的环境,并非一切都掌握在用户手中。共享通用基础设施给所有这些站点带来了许多挑战,但也为大范围的重大改进(也就是利用规模经济)铺平了道路。
找到共同语言
性能领域的一大核心问题是找到一种通用的术语来讨论各个方面的用户体验,同时考虑技术层面和感知层面的性能表现。在组织内使用定义明确的通用语言使我们能够轻松讨论和分类各种技术部分和权衡取舍、理解我们的性能报告,尤其重要的是帮助我们了解首先应该关注的改进领域。
我们调整了所有监视指标和内部讨论,加入了很多行业标准指标,如 Web Vitals,包括:

Core Web Vitals
网站的复杂性和性能得分
创建一个可以立即加载的网站很容易,只要你把它做的很简单,只使用 HTML 并通过 CDN 发布即可。

PageSpeed 洞察示例
但现实情况是,站点变得越来越复杂和精细,其运行方式越来越像应用程序而不是文档,并且支持诸如博客、电子商务解决方案和自定义代码等功能。
Wix 提供了种类繁多的模板,使用户可以轻松地构建具有许多业务功能的站点,而这些附加特性通常会带来一些性能成本。
旅程
一开始是 HTML
每次加载一个网页时,它总是以对一个 URL 的一个初始请求开始,用来检索 HTML 文档。这个 HTML 响应会触发所有其他客户端请求和浏览器逻辑来运行和渲染你的网站。这是最重要的页面加载步骤,因为在响应到达前什么都不会发生(称为 TTFB——第一个字节到达的时间)。

WebPageTest First View
过去:客户端渲染(CSR)
在运营大规模系统时总是需要权衡取舍各种因素,例如性能、可靠性和成本。直到几年前,Wix 都在使用客户端渲染(CSR),通过客户端(即浏览器)中的 JavaScript 来生成实际的 HTML 内容。这使我们能支持大量站点,而无需承担庞大的后端运营成本。
CSR 使我们能够使用一个通用的 HTML 文档,该文档实际上是空的。它所做的只是触发所需代码和数据的下载过程,然后用它们在客户端设备上生成完整的 HTML。
现在:服务端渲染(SSR)
几年前,我们过渡到服务端呈现(SSR),因为这对 SEO 和性能均颇有益处,缩短了初始页面可见时间,并能对不完全支持运行 JavaScript 的搜索引擎获得更好的索引结果。
这种方法改善了可见性体验,尤其是在速度较慢的设备/连接上,为进一步的性能优化打开了方便之门。但这也意味着对于每个网页请求,需要动态生成唯一的 HTML 响应,这远非理想之举,尤其是对具有大量视图的网站来说压力更为沉重。
在多个位置引入缓存
各个站点的 HTML 大部分都是静态的,但有一些需要注意:
它经常更改。每次用户编辑他们的站点或更改站点数据时,例如更改商店库存,HTML 都会变化。
它具有某些特定于访问者的数据和 cookie。这意味着访问同一站点的两个人会看到有些不同的 HTML。这种特性可以支持一些产品功能,例如记住访问者将哪些物品放入了购物车,或记住访问者之前同商家开始的聊天对话,等等。
并非所有页面都是可缓存的。例如,带有自定义用户代码的页面可能将当前时间显示为文档的一部分,因此无法缓存。
一开始,我们采用了一种相对安全的方法,即缓存没有访问者数据的 HTML,然后针对每个访问者为每个缓存命中动态修改 HTML 响应的特定部分。
内部 CDN 解决方案
为此我们部署了一个内部解决方案:使用Varnish HTTP Cache进行代理和缓存,使用 Kafka 来对消息无效化,还有一个基于 Scala/Netty 的服务,负责代理这些 HTML 响应,但会对 HTML 进行修改并向缓存的响应添加特定于访问者的数据和 cookie。
这个解决方案让我们能将这些轻巧的组件部署在遍布全球的更多地理位置和多个云提供商区域。2019 年,我们引入了超过 15 个新区域,并逐渐为 90%以上适合缓存的页面访问启用了缓存。从更多位置提供站点可以减少客户端和提供 HTML 响应的服务器之间的网络延迟,因为内容离网站访问者的距离更近了。
我们还开始使用相同的解决方案来缓存某些只读 API 响应,并在对网站内容进行任何更改时使缓存无效。例如,网站上的博客文章列表会被缓存,而有文章发布/修改时缓存会被无效化)。
降低复杂度
实现缓存可以显著提高性能(主要是在 TTFB 和 FCP 阶段),它让我们可以在更接近最终用户的位置提供内容,从而提高了可靠性。
但是,为每个响应修改 HTML 的做法引入了不必要的复杂性。如果能消除这种复杂性,就能为进一步提高性能创造条件。
浏览器缓存(以及为 CDN 做的准备)
HTML 请求直接从浏览器缓存中提供,从而节省了大量带宽并减少了重复视图的加载时间(~13%)
下一步是从 HTML 完全删除这部分特定于访问者的数据,并在 HTML 到达后从客户端为此目的调用的一个独立端点中检索这部分数据。
我们将这些数据和 cookie 小心地迁移到一个新端点,该端点在每次页面加载时都会被调用,但是返回一个轻巧的 JSON(只有水合流程才需要它),以实现完整的页面交互。
这样,我们就能启用浏览器对这个 HTML 的缓存,也就是说浏览器现在会为重复访问的站点存储 HTML 响应,并且只调用服务器来验证内容是否更改。这是使用HTTP ETag完成的,它基本上是一个识别器,被分配给 HTML 源的特定版本。如果内容没有变化,我们的服务器会向客户端发送一个 304 Not Modified 响应,其中没有正文。

WebPageTest Repeat View
此外,这一更改意味着我们的 HTML 不再是特定于访问者的,并且不再包含 Cookie。换句话说,它基本上可以缓存在任何地方,这样就可以充分利用 CDN 提供商的能力。这些 CDN 提供商的地理部署优势更大,在全球数百个位置都有部署。
DNS、SSL 和 HTTP/2
启用缓存后,等待时间减少,初始连接的其他重要部分也显得更加突出了。增强我们的网络基础架构和监视能力后,我们得以改善 DNS、连接和 SSL 时间。

响应时间图
我们已为所有用户域启用 HTTP/2,从而减少了所需的连接数量以及每个新连接的开销。这是相对容易部署的更改,同时利用了 HTTP/2 带来的性能和弹性优势。
Brotli 压缩(vs gzip)
减少文件传输大小中值(21-25%)
传统上,我们的所有文件都是用 gzip 压缩的(这是网络上最流行的 HTML 压缩选项),这个压缩协议最初是在 30 年前实现的!

Brotli 压缩级别估算器
较新的 Brotli 压缩引入了很多压缩改进,几乎没有任何负面代价,并且正逐渐流行起来。所有主流浏览器已经支持它有一段时间了。
我们所有支持的客户端在边缘的 nginx 代理上启用了 Brotli 支持。
转向 Brotli 压缩让我们的文件传输大小中值减少了 21%-25%,从而减少了带宽用量并缩短了加载时间。

响应大小中值
内容交付网络(CDN)
动态 CDN 选择
在 Wix,我们一直使用 CDN 在用户网站上提供所有 JavaScript 代码和图像。
最近,我们集成了一个 DNS 提供商的解决方案,可以根据客户端的网络和区域自动选择性能最好的 CDN。这让我们能为每个访问者从最佳位置提供静态文件,并避免某些 CDN 的可用性问题。
即将推出……CDN 提供的用户域
问题的最后一部分是通过 CDN 提供最后,也是最关键的部分:用户域中的 HTML。
如上所述,我们创建了自己的内部解决方案来缓存和提供特定于站点的 HTML 和 API 结果。在这么多新区域维护这个方案是有运营成本的,添加新区域的流程也需要我们不断维护和优化。
目前,我们正在集成多个 CDN 提供商,以支持直接从 CDN 位置提供整个 Wix 站点,从而改善我们的服务器在全球范围内的分发效率,进一步缩短响应时间。由于我们服务的域众多,因此这是一个挑战,需要在边缘进行 SSL 终止。
与 CDN 集成使 Wix 网站比以往任何时候都更贴近客户,并且在加载体验方面有了更多改进(包括诸如 HTTP/3 之类的更新技术),而这些改进无需我们付出更多努力。
关于性能监控
如果你在运营一个 Wix 网站,你可能想知道这些改进是如何转变为 Wix 网站性能结果的,以及我们如何与其他网站平台进行比较。
上面完成的大多数工作都在过去的一年中部署完毕,而有些工作仍在推广中。
HTTPArchive 的 Web 年鉴(Web Almanac)最近发布了2020年版,其中包括有关 CMS 用户体验的一个精彩章节。请记住,本文中提到的许多数字都是从 2020 年中期开始的。
我们期待在 2021 年看到更新后的报告,并正在积极监控我们站点的 CrUX 报告以及我们的内部性能指标。
我们致力于不断改善加载时间,并为我们的用户提供一个平台,让他们可以在不影响性能的前提下构建自己理想的网站。

移动网站的 LCP、速度指数和 FCP 的长期变化
DebugBear 最近发布了一个非常有趣的“网站构建器性能评估”,它涉及了我上面提到的某些领域,并检查了在每个平台上构建的非常简单的网站的性能。该网站建于大约两年前,此后未做过修改,但是平台还在持续改进,网站性能也随之提高。查看过去一年半的数据就可以找到证据。
结论
我们希望我们的经验能激励你在组织中推行以性能为导向的文化,也希望上面的信息对你的平台或站点能有帮助。
总结一下:
选择一组可以使用行业认可的工具进行一致跟踪的指标,我们建议你使用 CoreWebVitals。
利用浏览器缓存和 CDN。
迁移到 HTTP/2(如果可能,迁移到 HTTP/3)。
使用 Brotli 压缩。
原文链接:
评论