基于数据的建议,旨在通过 Core Web Vitals 延迟加载图片。
延迟加载是一种将资源下载推迟到需要时才进行的技术,旨在节省数据流量并减少关键资源的带宽争用。它于 2019 年成为网络标准,如今大多数主流浏览器都支持图片的 loading="lazy"。
本指南总结了如何分析公开的网络透明度数据和临时 A/B 测试,以了解浏览器级图片延迟加载的采用情况和性能特征。研究结果包括:延迟加载可以非常有效地减少不必要的图片字节,但过度使用可能会对性能产生负面影响。具体而言,此分析表明,在初始视口中更积极地加载图片,同时对其余图片进行自由延迟加载,可以让我们两全其美:加载的字节数更少,Core Web Vitals 得到改善。
采用
根据 HTTP Archive 中的最新数据,29% 的网站使用了内置图片延迟加载功能,并且采用率正在快速增长。
通过查询 HTTP Archive 项目中的原始数据,我们可以更清楚地了解哪些类型的网站在推动采用:在使用浏览器级图片延迟加载的网站中,84% 使用 WordPress,2% 使用其他 CMS,其余 14% 未使用已知 CMS。这些结果清楚地表明,WordPress 在采用率方面处于领先地位。
采用率也值得注意。一年前,即 2020 年 7 月,在约 600 万个网站(占总数的 1%)中,使用延迟加载的 WordPress 网站有数万个。自此之后,仅在 WordPress 中采用延迟加载的网站数量就已增长到 100 万以上(占总数的 14%)。
相关性表现
深入研究 HTTP Archive,可以比较采用和未采用浏览器级图片延迟加载的网页在 Largest Contentful Paint (LCP) 指标方面的表现。LCP 数据来自 Chrome 用户体验报告 (CrUX) 中的真实用户体验,而不是实验室中的合成测试。以下图表使用箱线图直观呈现了每个网页的第 75 百分位 LCP 的分布情况:线条表示第 10 百分位和第 90 百分位,方框表示第 25 百分位和第 75 百分位。
未采用延迟加载的网页的 LCP 第 75 百分位值为 2,922 毫秒,而采用延迟加载的网页的 LCP 第 75 百分位值为 3,546 毫秒。总体而言,使用延迟加载的网站往往 LCP 性能较差。
需要指出的是,这些是相关性结果,并不一定表明延迟加载是性能下降的原因。假设 WordPress 网站往往稍慢一些,并且考虑到它们在延迟加载群组中所占的比例,这或许可以解释这种差异。为了消除这种不确定性,可以将重点专门放在 WordPress 网站上。
遗憾的是,在深入分析 WordPress 网页时,也出现了同样的模式:使用延迟加载的网页往往 LCP 性能较慢。未采用延迟加载的 WordPress 网页的 LCP 第 75 百分位值为 3,495 毫秒,而采用延迟加载的网页的 LCP 第 75 百分位值为 3,768 毫秒。
这仍然无法证明延迟加载导致网页变慢,但使用延迟加载确实与性能变慢同时发生。为了回答因果关系问题,我们设置了一个基于实验室的 A/B 测试。
因果效果
A/B 测试的目标是证明或反驳以下假设:WordPress 核心中实现的内置图片延迟加载会导致 LCP 性能降低和图片字节数减少。所用方法是测试一个采用 twentytwentyone 主题的 WordPress 演示网站。我们使用 WebPageTest 在桌面设备和模拟移动设备上测试了归档和单页类型(类似于首页和文章页)。我们测试了启用和未启用延迟加载的网页的每种组合,并且每项测试都运行了 9 次,以获取 LCP 值和图片字节数的中位数。
| 系列 | 默认 | 已停用 | 与默认值的差异 |
|---|---|---|---|
| twentytwentyone-archive-desktop | 2,029 | 1,759 | -13% |
| twentytwentyone-archive-mobile | 1,657 | 1,403 | -15% |
| twentytwentyone-single-desktop | 1,655 | 1,726 | 4% |
| twentytwentyone-single-mobile | 1,352 | 1,384 | 2% |
这些结果比较了桌面设备和移动设备上归档页面和单个页面测试的 LCP 中位数(以毫秒为单位)。在归档页面上停用延迟加载后,LCP 得到了显著改善。不过,在单页上,这种差异并不明显。
停用延迟加载似乎可以略微提高单页加载速度。不过,在桌面设备和移动设备测试中,LCP 的差异均小于一个标准差,因此这可能是由方差引起的,总体而言,该更改的影响是中性的。相比之下,归档页面的差异更接近两到三个标准差。
| 系列 | 默认 | 已停用 | 与默认值的差异 |
|---|---|---|---|
| twentytwentyone-archive-desktop | 577 | 1173 | 103% |
| twentytwentyone-archive-mobile | 172 | 378 | 120% |
| twentytwentyone-single-desktop | 301 | 850 | 183% |
| twentytwentyone-single-mobile | 114 | 378 | 233% |
这些结果比较了每项测试的图片字节数中位数(以 KB 为单位)。正如预期,延迟加载在减少图片字节数方面具有非常明显的积极效果。如果真实用户滚动浏览整个网页,所有图片都会在进入视口时加载,但这些结果显示了初始网页加载性能的提升。
总结 A/B 测试的结果,WordPress 使用的延迟加载技术显然有助于减少图片字节数,但代价是 LCP 延迟。
测试修正效果
对于此实验,WordPress 当前延迟加载实现的最重要方面是,它会延迟加载视口内(首屏)的图片。CMS 博文承认这是一种应避免的模式,但当时的实验数据表明,对 LCP 的影响微乎其微,值得简化 WordPress 核心中的实现。
根据这些新数据,我们创建了一个实验性修复程序,以避免延迟加载首屏图片,并在与第一个 A/B 测试相同的条件下测试了该修复程序。
| 系列 | 默认 | 已停用 | 修正 | 与默认值的差异 | 与停用状态的区别 |
|---|---|---|---|---|---|
| twentytwentyone-archive-desktop | 2,029 | 1,759 | 1,749 | -14% | -1% |
| twentytwentyone-archive-mobile | 1,657 | 1,403 | 1,352 | -18% | -4% |
| twentytwentyone-single-desktop | 1,655 | 1,726 | 1,676 | 1% | -3% |
| twentytwentyone-single-mobile | 1,352 | 1,384 | 1,342 | -1% | -3% |
这些结果更令人满意。仅延迟加载非首屏图片,不仅可以完全扭转 LCP 性能下降的趋势,甚至可能比完全停用延迟加载略有提升。怎么可能比完全不延迟加载更快呢?一种解释是,通过不加载首屏下方的图片,与 LCP 图片的网络争用减少,从而使其加载速度更快。
| 系列 | 默认 | 已停用 | 修正 | 与默认值的差异 | 与停用状态的区别 |
|---|---|---|---|---|---|
| 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 会在服务器端确定要延迟加载哪些图片,这意味着它对用户的视口大小或图片是否最初在视口中加载一无所知。因此,该修复程序会根据标记中图片的相对位置,使用启发法来猜测图片是否在视口中加载。具体而言,如果图片是网页上的第一张精选图片或主要内容中的第一张图片,则系统会假定该图片位于首屏或靠近首屏,并且不会延迟加载。
网页级条件(例如标题中的字数或主要内容开头处的段落文本量)可能会影响图片是否位于视口内。此外,还有一些用户级条件可能会影响启发法的准确性,尤其是视口大小以及使用会改变网页滚动位置的锚链接。
因此,请务必注意,此修复仅经过校准,可在一般情况下提供良好性能,可能需要进行微调才能使这些结果适用于所有实际场景。
实现
既然已经找到了更好的图片延迟加载方式,不仅能节省图片资源,还能提升 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 核心中很快就会有补丁。如果您使用的是其他 CMS,请确保他们了解此处所述的潜在性能问题。
试用相对较新的 Web 平台 API 既有风险,也有回报,因此它们被称为前沿功能。虽然我们开始意识到浏览器级图片延迟加载的棘手之处,但我们也看到了如何使用它来实现更好的性能。