以 Core Web Vitals 为目标,提供数据驱动的延迟加载图片建议。
延迟加载是一种技术,可将资源的下载推迟到需要时,以节省数据并减少对关键资源的网络争用。它在 2019 年成为 Web 标准,如今,大多数主流浏览器都支持适用于图片的 loading="lazy"
。
本指南总结了我们如何分析公开可用的网站透明度数据和临时 A/B 测试,以了解浏览器级图片延迟加载的采用情况和性能特征。研究结果表明,延迟加载可以非常有效地减少不需要的图片字节,但过度使用可能会对性能产生负面影响。具体而言,这项分析表明,在初始视口内更积极地加载图片(同时尽可能延迟加载其余图片),可以两全其美:减少加载的字节数并改善核心 Web Vitals 指标。
采用
根据 HTTP Archive 中的最新数据,29% 的网站在使用内置图像延迟加载功能,而且采用率正在快速增长。
通过查询 HTTP Archive 项目中的原始数据,我们可以更清楚地了解哪些类型的网站在推动采用浏览器级图片延迟加载:84% 使用浏览器级图片延迟加载的网站使用 WordPress,2% 使用其他 CMS,其余 14% 不使用已知的 CMS。这些结果清楚地表明,WordPress 在采用率方面处于领先地位。
采用率也值得注意。一年前的 2020 年 7 月,在约 600 万个网站的语料库中,使用延迟加载的 WordPress 网站仅有数万个(占总数的 1%)。自那时起,仅 WordPress 就已采用延迟加载的网站超过 100 万个(占总数的 14%)。
相关性效果
深入研究 HTTP Archive,您可以通过 Largest Contentful Paint (LCP) 指标比较启用和未启用浏览器级图片延迟加载的网页的性能。LCP 数据来自 Chrome 用户体验报告 (CrUX) 中的真实用户体验,而不是实验室中的合成测试。下图使用箱线图直观显示了每个网页的 75 百分位 LCP 的分配情况:线条代表第 10 百分位和第 90 百分位,箱子代表第 25 百分位和第 75 百分位。
未启用延迟加载的中位数网页的 75 百分位 LCP 为 2,922 毫秒,而启用延迟加载的中位数网页的 75 百分位 LCP 为 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 差异均小于一个标准差,因此这可能归因于方差,总体而言,变化不大。相比之下,归档页的差异更接近于 2 到 3 个标准差。
系列 | 默认 | 已停用 | 与默认值的差异 |
---|---|---|---|
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 图片的次数会减少,从而加快 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 既有风险也有回报,它们之所以被称为前沿功能,是有原因的。虽然我们开始了解浏览器级图片延迟加载的棘手之处,但也看到了如何使用它来实现更好性能的好处。
照片由 Frankie Lopez 拍摄,选自 Unsplash