以 Core Web Vitals 为目标,提供数据驱动的延迟加载图片建议。
延迟加载是一种将资源下载延迟到需要时再下载的技术,可节省数据并减少对关键资源的网络争用。它在 2019 年成为 Web 标准,如今,大多数主流浏览器都支持适用于图片的 loading="lazy"
。
本指南总结了我们如何分析公开可用的网站透明度数据和临时 A/B 测试,以了解浏览器级图片延迟加载的采用情况和性能特征。研究结果表明,延迟加载可以非常有效地减少不需要的图片字节,但过度使用可能会对性能产生负面影响。具体来说,此分析表明,在初始视口内更急切地加载图片(同时随意延迟加载其余图片)可以两全其美:加载的字节数更少,以及核心网页指标。
采用
根据 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,000 | 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,000 | 1,403,000 | 1,352 | -18% | -4% |
twentytwentyone-single-desktop | 1,655 | 1,726 | 1,676 | 1% | -3% |
twentytwentyone-single-mobile | 1,352 | 1,384,000 | 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,请确保他们了解本文中所述的潜在性能问题。
试用相对较新的网络平台 API 会带来风险和回报 - 它们之所以称之为尖端功能,是有其原因的。虽然我们开始了解浏览器级图片延迟加载的棘手之处,但也看到了如何使用它来实现更好性能的好处。
照片由 Frankie Lopez 拍摄于 Unsplash 网站