延迟加载过多对性能的影响

以数据为依据提出延迟加载图片的建议,并牢记核心网页指标。

Felix Arntz
Felix Arntz

延迟加载是一种将资源下载延迟到需要时再下载的技术,可节省数据并减少对关键资源的网络争用。该格式在 2019 年成为了网络标准,如今,大多数主流浏览器都支持针对图片的 loading="lazy"

本指南总结了如何分析公开提供的网络透明度数据和临时 A/B 测试,以了解浏览器级图片延迟加载的采用情况和性能特征。研究结果包括,在减少不需要的图片字节数方面,延迟加载可以是一个非常有效的工具,但过度使用会对性能产生负面影响。具体而言,此分析表明,在初始视口内以较为急切的方式加载图片(同时随意延迟加载其余图片)可以两全其美:加载的字节数更少,以及核心网页指标

采用

根据 HTTP Archive 的最新数据,29% 的网站使用内置图片延迟加载功能,且采用率在快速增长。

一张饼图,显示 WordPress 占延迟加载采用率的 84.1%,其他 CMS 的采用率为 2.3%,非 CMS 的采用率为 13.5%。
利用浏览器级图片延迟加载的网站类型的细分数据。来源

通过查询 HTTP Archive 项目中的原始数据,我们可以更清楚地了解哪些类型的网站正在推动采用:在使用浏览器级图片延迟加载的网站中,84% 使用 WordPress,2% 使用其他 CMS,其余 14% 未使用已知的 CMS。这些结果说明了 WordPress 如何引领客户采用 Google Cloud

时间序列图表,显示与其他 CMS 和非 CMS 相比,以 WordPress 占据主导地位的延迟加载采用情况,比例与上一个图表中大致相当。数据显示,从 2020 年 7 月到 2021 年 6 月,总采用率从 1% 迅速上升到 17%。
利用浏览器级图片延迟加载的网站类型的细分数据。来源

此外,采用率也值得关注。一年前的 2020 年 7 月,使用延迟加载的 WordPress 网站构成了数万个网站,语料库约为 600 万个(占总数的 1%)。此后,仅在 WordPress 采用的延迟加载技术已发展到超过 100 万个网站(占网站总数的 14%)。

相关性性能

深入了解 HTTP Archive 后,您可以参考 Largest Contentful Paint (LCP) 指标,对比使用和不使用浏览器级图片延迟加载的网页的性能。LCP 数据来自 Chrome 用户体验报告 (CrUX) 中的真实用户体验,而不是实验室中的合成测试。以下图表使用箱须图直观呈现每个网页的第 75 个百分位的 LCP 分布情况:线条表示第 10 和 90 百分位,方框表示第 25 和 75 百分位。

箱须图 - 显示了使用和不使用浏览器级图片延迟加载的网页的第 10、25、75 和 90 百分位数。相比之下,对于不使用 LCP 的网页,其 LCP 分布情况要比使用该网页的速度快。
所有网页第 75 个百分位的 LCP 体验的分布情况(按是否使用浏览器级图片延迟加载细分)。来源

未采用延迟加载时中位数网页的 LCP 为第 75 个百分位,LCP 为 2,922 毫秒,而采用延迟加载的中位数网页的 LCP 值为 3,546 毫秒。总体而言,使用延迟加载的网站的 LCP 性能往往更差。

请务必注意,这些结果具有相关性,不一定表示延迟加载是导致性能下降的原因。假想一下,如果 WordPress 网站的速度往往有点慢,考虑到它们在延迟加载同类群组中的占比,这可能就是造成差异的原因。为了消除这种差异,可以将关注范围缩小到专门介绍 WordPress 网站。

显示使用和不使用浏览器级图片延迟加载的 WordPress 网页的 10、25、75 和 90 百分位的箱须图。相比之下,与上一个图表类似,不使用 LCP 的网页的 LCP 分布速度要比使用前者快的网页快。
WordPress 网页第 75 个百分位的 LCP 体验分布情况(按是否使用浏览器级图片延迟加载进行了细分)。来源

遗憾的是,深入到 WordPress 网页时也会出现相同的模式;使用延迟加载的网页往往具有较低的 LCP 性能。不使用延迟加载的 WordPress 中位数网页的 LCP 第 75 个百分位为 3,495 毫秒,而采用延迟加载的中位数网页的 LCP 值为 3,768 毫秒。

这仍无法证明延迟加载会导致网页变慢,但使用延迟加载与性能变慢是同时存在的。为尝试回答因果关系问题,我们设置了基于实验室的 A/B 测试。

因果效果

A/B 测试旨在证明或反驳以下假设:在 WordPress 核心中实现的内置图片延迟加载会导致 LCP 性能降低和图片字节数减少。他们采用的方法是测试以 twentytwentyone 为主题的演示版 WordPress 网站。在桌面设备和模拟移动设备上,我们分别使用 WebPageTest 对归档页和单页类型(与首页和文章页类似)进行了测试。我们对启用了和未启用延迟加载的网页组合进行了测试,且每项测试均运行了 9 次,以获取 LCP 中位数值和图片字节数。

系列 default 已停用 与默认值的差异
twentytwentyone-archive-desktop 2,029,000 1,759,000 -13%
twentytwentyone-archive-mobile 1,657,000 1,403,000 -15%
twentytwentyone-single-desktop 1,655,000 1,726,000 4%
twentytwentyone-single-mobile 1,352,000 1,384,000 2%
在示例 WordPress 页面上停用浏览器级图片延迟加载后,LCP 的变化(毫秒)。

这些结果比较了针对归档网页以及针对桌面设备和移动设备测试的单页测试的 LCP 中间值(以毫秒为单位)。在归档页面上停用延迟加载后,LCP 性能得到了显著提升。但是,在单个网页上,效果没那么大。

停用延迟加载似乎使单页速度略有提升。然而,桌面设备和移动设备测试的 LCP 差异都小于 1 个标准差,因此这可归因于差异,并将变化视为中性。相比之下,归档页面的差值接近两到三个标准差。

系列 default 已停用 与默认值的差异
twentytwentyone-archive-desktop 577 1173 103%
twentytwentyone-archive-mobile 172 378 120%
twentytwentyone-single-desktop 301 850 183%
twentytwentyone-single-mobile 114 378 233%
在示例 WordPress 页面上停用浏览器级图片延迟加载后,图片字节数 (KB) 的变化。

这些结果比较了每个测试的图片字节数中位数(以 KB 为单位)。不出所料,延迟加载对减少图片字节数有非常明显的积极影响。如果真实用户滚动浏览整个页面,则所有图片无论如何都会在跨入视口时进行加载,但这些结果表明初始页面加载的性能有所提升。

A/B 测试的结果总结如下:WordPress 使用的延迟加载技术非常明显有助于减少图片字节数,但代价是 LCP 会延迟。

测试修正效果

对于本实验,WordPress 当前采用的延迟加载实现方案最重要的一点是,它能够在视口(首屏)内延迟加载图片。该 CMS 博文承认这是一种要避免的模式,但当时的实验数据表明,对 LCP 的影响微乎其微,值得简化在 WordPress 核心中的实现。

根据这些新数据,我们制定了一项实验性修复方案来避免延迟加载首屏图片,并在与第一次 A/B 测试相同的条件下对该修复方案进行了测试。

系列 default 已停用 fix 与默认值的差异 与已停用的区别
twentytwentyone-archive-desktop 2,029,000 1,759,000 1,749,000 -14% -1%
twentytwentyone-archive-mobile 1,657,000 1,403,000 1,352,000 -18% -4%
twentytwentyone-single-desktop 1,655,000 1,726,000 1,676,000 1% -3%
twentytwentyone-single-mobile 1,352,000 1,384,000 1,342,000 -1% -3%
针对 WordPress 示例网页上的浏览器级图片延迟加载问题提议的 LCP 变化(毫秒)。

这些结果的前景要大得多。仅延迟加载非首屏的图片可完全逆转 LCP 回归,甚至可能比完全停用延迟加载略有改进。怎么会比完全不延迟加载更快呢?一种原因在于,通过不加载非首屏图片,可以减少与 LCP 图片的网络争用,从而提高其加载速度。

系列 default 已停用 fix 与默认值的差异 与已停用的区别
twentytwentyone-archive-desktop 577 1173 577 0% -51%
twentytwentyone-archive-mobile 172 378 172 0% -54%
twentytwentyone-single-desktop 301 850 301 0% -65%
twentytwentyone-single-mobile 114 378 114 0% -70%
针对 WordPress 示例网页上的浏览器级图片延迟加载提出的解决方案,图片字节数 (KB) 发生了变化。

就映像字节而言,与默认行为相比,此修复绝对没有变化。这是很好的,因为这是当前方法的优势之一。

修复此问题时有一些注意事项。WordPress 会决定在服务器端延迟加载哪些图片,这意味着它不知道用户的视口大小,也不知道最初是否会在其中加载图片。因此,修复程序会使用关于图片在标记中相对位置的启发法来猜测图片是否在视口中加载。具体而言,如果图片是网页上的第一张精选图片或主要内容中的第一张图片,系统会假定该图片位于首屏或贴近图片,并且不会被延迟加载。

网页级条件(例如标题中的字词数量或主要内容中较早的段落文字数量)可能会影响图片是否在视口内。此外,还有可能影响启发式算法准确性的用户级条件,特别是视口大小以及使用锚链接来改变页面滚动位置的情况。

出于这些原因,请务必承认,修正方法只是为了在一般情况下提供良好性能而进行校准,并且可能需要微调才能使这些结果适用于所有实际场景。

实现 (:#implementation)

现在,我们已确定了一种更好的图片延迟加载方法,可以节省所有图片并加快 LCP 性能,那么网站该如何开始使用它呢?优先级最高的更改是向 WordPress 核心提交补丁,以实施实验性修复。CMS 的浏览器级延迟加载博文中的指南也将更新,以阐明首屏延迟加载的负面影响,以及 CMS 如何利用启发法来避免这种情况。

由于这些最佳实践适用于所有 Web 开发者,因此可能还有必要在 Lighthouse 等工具中标记延迟加载反模式。如果您有兴趣了解该审核的进展情况,请参阅 GitHub 上的功能请求。在此之前,开发者要想查找被延迟加载的 LCP 元素实例,可以采取一项措施,那就是在其字段数据中添加更详细的日志记录。

new PerformanceObserver((list) => {
  const latestEntry = list.getEntries().at(-1);

  if (latestEntry?.element?.getAttribute('loading') == 'lazy') {
    console.warn('Warning: LCP element was lazy loaded', latestEntry);
  }
}).observe({type: 'largest-contentful-paint', buffered: true});

上述 JavaScript 代码段将评估最新的 LCP 元素,并在元素被延迟加载时记录警告。

这也凸显了延迟加载技术的尖端,以及平台层面的 API 改进潜力。例如,Chromium 中有一个待解决的问题,可用于实验以原生方式快速加载前几张图片,这与修复程序(尽管具有 loading 属性)类似。

总结

如果您的网站使用浏览器级图片延迟加载,请检查其实现方式并运行 A/B 测试,以便更好地了解其性能成本。如果能更快地加载首屏图片,效果可能会更上一层楼。如果您有 WordPress 网站,我们应该很快就会在 WordPress Core 中推出一个补丁。如果您使用的是其他 CMS,请确保它们知晓此处所述的潜在性能问题。

试用相对较新的网络平台 API 可能会带来风险和回报 - 它们之所以称之为尖端功能,是有其原因的。在开始了解浏览器级图片延迟加载的棘手性的同时,我们也看到了如何利用它提升性能的优点。

照片由 Frankie Lopez 拍摄于 Unstone