案例研究,了解 Wix 为提升数百万个网站的网站加载性能而做出的一些重大变更,为这些网站扫清获得良好 PageSpeed Insights 和核心网页指标得分的途径。
得益于业界标准、云提供商和 CDN 功能,再加上我们对网站运行时的重大改写,根据 CrUX 和 HTTPArchive 提供的数据,Wix 网站在所有核心网页指标指标上第 75 百分位的得分年同比增加了两倍以上。
Wix 采用了以性能为导向的文化,我们会继续向用户推出进一步的改进。当我们重点关注性能 KPI 时,预计超过 Core Web Vitals 阈值的网站数量会不断增加。
概览
性能世界非常复杂,涉及许多变数和复杂性。研究表明,网站速度会对企业的转化率和收入产生直接影响。近年来,业界更加注重性能可见性和提升 Web 速度。从 2021 年 5 月开始,网页体验信号将纳入 Google 搜索排名中。
Wix 面临的独特挑战是为数百万个网站提供支持,其中一些网站是多年前构建的,此后一直没有更新过。我们提供各种工具和文章,帮助用户了解可以采取哪些措施来分析和改进网站的性能。
Wix 是一个托管式环境,并非所有工作都掌握在用户手中。 共享通用基础架构会给所有这些站点带来许多挑战,但同时也为全面实现重大改进(即利用规模经济)创造了机会。
讲同一种语言
性能方面的核心难点之一是,在同时考虑技术性能和感知性能的同时,找到一个通用术语来讨论用户体验的不同方面。通过在组织内使用明确定义的通用语言,我们能够轻松地讨论和分类不同的技术部分和权衡因素,阐明效果报告,极大地帮助我们了解应该首先关注哪些方面。
我们调整了所有监控和内部讨论,以纳入网页指标等业界标准指标,这些指标包括:

网站复杂性和性能得分
创建可即时加载的网站非常简单,只要您仅使用 HTML 简化这一过程并通过 CDN 提供它即可。

然而,现实情况是,网站变得越来越复杂和复杂,其操作方式更像应用而不是文档,并支持博客、电子商务解决方案、自定义代码等功能。
Wix 提供了非常多样的模板,让用户能够轻松构建具有多种业务功能的网站。这些额外的功能通常会带来一些性能下降。
旅程
最开始,
每次加载网页时,网页总是先对网址发出初始请求,以便检索 HTML 文档。此 HTML 响应会触发所有其他客户端请求和浏览器逻辑来运行和呈现您的网站。这是网页加载过程中最重要的部分,因为在响应的开头到达(称为 TTFB,即转到第一个字节的时间)之前,不会发生任何变化。

过去:客户端呈现 (CSR)
运行大型系统时,您始终需要权衡需要考虑的性能、可靠性和费用。直到几年前,Wix 一直使用客户端渲染 (CSR),这种方法的实际 HTML 内容是在客户端(即在浏览器中)通过 JavaScript 生成的,这让我们能够支持大规模的网站,而不会产生巨大的后端运营成本。
CSR 让我们可以使用基本为空的通用 HTML 文档。它只是触发了下载所需代码和数据,随后利用这些数据在客户端设备上生成完整的 HTML。
目前:服务器端渲染 (SSR)
几年前,我们采用了服务器端呈现 (SSR),因为这种技术对 SEO 和性能都非常有益,既能缩短网页的初始曝光时间,又能确保为不完全支持运行 JavaScript 的搜索引擎提供更好的索引编制效果。
这种方法提升了可见性体验,尤其是在设备/连接速度较慢时,也为进一步优化性能提供了大门。不过,这也意味着,对于每个网页请求,都会实时生成唯一的 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 的准备工作)
约 13%
直接从浏览器缓存传送 HTML 请求,可以节省大量带宽并缩短重复查看的加载时间
下一步是从 HTML 完全移除此访问者专用数据,并在 HTML 收到后从客户端为此调用的单独端点检索这些数据。
我们仔细地将这些数据和 Cookie 迁移到了新端点,该端点在每次网页加载时都会调用,但会返回精简 JSON(只有饮水过程需要此端点来实现完整的网页互动)。
这样一来,我们就可以启用 HTML 的浏览器缓存,这意味着浏览器现在会保存 HTML 响应以供重复访问使用,并且仅调用服务器来验证内容是否未更改。这是使用 HTTP ETag 完成的,后者基本上是分配给特定 HTML 资源版本的标识符。如果内容保持不变,我们的服务器会向客户端发送 304 Not Modified 响应(没有正文)。

此外,这项变更还意味着,我们的 HTML 不再特定于访问者,也不会包含 Cookie。换句话说,它基本上可以缓存在任何地方,这为使用在世界各地数百个位置拥有更好地理位置的 CDN 提供商打开了大门。
DNS、SSL 和 HTTP/2
启用缓存后,等待时间缩短,初始连接的其他重要部分变得更加强大。通过加强网络基础架构和监控功能,我们能够改进 DNS、连接和 SSL 时间。

为所有用户网域启用了 HTTP/2,这减少了所需的连接数和每个新连接产生的开销。这是一项相对容易部署的更改,同时充分利用了 HTTP/2 带来的性能和弹性优势。
Brotli 压缩(与 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 年历》最近发布了 2020 版,其中包含一个精彩的章节,专门阐述了 CMS 用户体验。请注意,本文中所述的许多数据都是 2020 年年中的数据。
我们期待在 2021 年看到更新后的报告,并且正在积极监控我们网站的 CrUX 报告以及内部效果指标。
我们致力于不断缩短加载时间,并为用户提供一个平台,让他们可以在不影响性能的情况下构建自己想象的网站。

DebugBear 最近发布了一份非常有趣的网站开发工具性能评估,其中涵盖了我上述一些方面,并分析了在每个平台上构建的简单网站的性能。网站大约两年前构建而成,自此未曾修改过,但该平台在不断改进,网站性能也在不断改善,您可以通过查看其数据了解其过去一年半的时间。
总结
我们希望我们的经验能激励您在您的组织中养成以绩效为导向的文化,并且上述详细信息对您的平台或网站有帮助且适用于您的平台。
总而言之:
- 选择一组可使用行业认可的工具持续跟踪的指标。我们建议使用 Core Web Vitals。
- 利用浏览器缓存和 CDN。
- 迁移到 HTTP/2(或 HTTP/3,如果可能)。
- 使用 Brotli 压缩。
感谢您学习我们的故事,我们邀请您在 Twitter 和 GitHub 上提问、分享想法,并在您喜爱的频道上参加网络性能讨论。