关于优化 LCP 的常见误解

Brendan Kenny
Brendan Kenny

网页的 Largest Contentful Paint (LCP) 可能很难改进,通常需要涉及多个活动部分并做出取舍。此博文着眼于整个网络中实际网页加载的实测数据,以确定开发者应重点优化哪些方面。

经典 LCP 建议:缩减图片大小!

对于网络上的大多数网页,LCP 元素都是图片。因此,人们自然会认为改善 LCP 的最佳方法是优化 LCP 图片。

在 LCP 问世后的大约五年里,这一直是大势所趋。请确保图片尺寸合适且经过充分压缩,在制作图片时也可以采用 21 世纪的图片格式。Lighthouse 甚至有三种 不同的 审核来提出这些建议。

<ph type="x-smartling-placeholder">
</ph> Lighthouse 报告中的三项映像优化审核 <ph type="x-smartling-placeholder">
</ph> Lighthouse 报告中的三项映像优化审核。

之所以如此常见建议,原因之一是:过多的字节易于测量,且易于推荐图像压缩工具。根据您的构建和部署流水线,实现起来可能也很简单。

如果有,就去执行吧!向用户发送的字节数很少会带来优势。网络上有许多网站仍在提供不必要的大图片,即使进行基本压缩就可以解决问题。

然而,当我们开始查看 Chrome 中用户的现场性能数据,了解 LCP 时间通常都花在哪些地方时,我们发现图片下载时间几乎从未成为瓶颈。

相反,LCP 的其他部分是一个大得多的问题。

LCP 子部分细分

为了了解改进 LCP 的最大机会领域,我们查看了 LCP 子部分的数据,如优化 LCP 中所述。

虽然每个网页和每个框架都可能会采用不同的方法来加载和显示将成为网页 LCP 元素的内容,但每个网页都可以分为以下子部分:

LCP 明细,显示四个子部分

引用该文章中的各子部分如下:

首字节时间 (TTFB)
从用户开始加载网页到浏览器加载网页之间的时间 接收 HTML 文档响应的第一个字节。
资源加载延迟
从 TTFB 到浏览器开始加载 LCP 资源所用的时间。如果 LCP 元素不需要加载资源即可渲染,现为 0
资源加载时长
加载 LCP 资源本身所用的时长。如果 LCP 元素不需要加载资源即可渲染,时间为 0
元素渲染延迟
从 LCP 资源完成加载到 LCP 元素完成加载之间的时间 完全呈现。

真实的导航性能数据

一个条形图,直观显示每个 LCP 子部分所花费的时间差异,分为“良好”“需要改进”和“较差”的 LCP 类别。TTFB 和加载延迟时间在持续时间上快速增加,而加载持续时间和渲染延迟时间仍然很短。下表中重现了数据

LCP 分级 TTFB(毫秒) 图片加载延迟(毫秒) 图片加载时长(毫秒) 渲染延迟(毫秒)
良好 600 350 160 230
需要改进 1,360,000 720 270 310
2,270,000 1290 350 360

在这篇博文中,我们使用了 Chrome 中带有子资源图片 LCP 的网页导航数据来查看 LCP 子部分。我们以前了解过此类数据,但从未通过实测数据来了解真实用户在等待网页 LCP 时将时间花在了何处。

与 Core Web Vitals 一样,对于 CrUX 数据集中每个来源的每个 LCP 子部分,我们选取了第 75 个百分位 (p75),从而得出 p75 值的 4 次分布(每个子部分各一个)。为了总结这些分布情况,我们针对四个 LCP 子部分分别取了所有源中这些值的中位数。

最后,我们根据源是“良好”“需要改进”还是“较差”将来源划分为多个分桶第 75 百分位的 LCP。这有助于显示 LCP 良好与 LCP 不良的来源有何区别。

要缩减 LCP 图片的大小吗?这次有数据

加载时长用于衡量提取 LCP 资源(在本例中为图片)所需的时间。该时间通常与映像中的字节数成正比,因此所有减少该字节数的性能建议都是如此。

从前面的图表中时间趋势来看,有一点也值得注意,那就是图片加载时长没有花费很多时间。事实上,在所有 LCP 分桶中,它是最短的 LCP 子部分。与 LCP 性能良好的源相比,LCP 性能不佳的来源的加载时长更长,但这并不是耗费大量时间的因素。

大多数 LCP 表现不佳的来源在下载 LCP 映像时所花的时间都不到其 p75 LCP 时间的 10%。

是的,您应确保对图片进行优化,但这只是改进 LCP 的一个环节。从这些数据可以看出,对于网络上的典型来源,无论压缩方案有多复杂,LCP 整体上的潜在毫秒增益都很小。

<ph type="x-smartling-placeholder">

最后令人惊讶的是,加载速度过慢通常是在移动设备上和移动网络的质量造成的。我们可能曾以为,普通手机要像使用有线连接的桌面设备一样要多次下载同一张图片。数据显示,情况不再如此。对于 LCP 较低的来源,P75 图片在移动设备上的加载时间中位数仅比桌面设备慢 20%。

首字节时间 (TTFB)

对于发出网络请求的导航,TTFB 始终需要一些时间。执行 DNS 查找和启动连接需要花费一些时间。物理问题无与伦比:一项请求必须通过电线和光缆在现实世界中穿行才能到达服务器,然后响应必须返回该服务器。即使是具有良好 LCP 的中位数来源,在第 75 个百分位的 TTFB 上花费的时间也超过半秒。

然而,良好 LCP 源与不良 LCP 源之间的 TTFB 差异表明了改进空间。对于至少一半的 LCP 较差的来源来说, 2,270 毫秒的 p75 TTFB 几乎可以保证 p75 LCP 不会比 2.5 秒的“良好”快阈值。即便是该时间的适度缩短百分比,也意味着 LCP 会得到显著提升。

你可能无法通过物理验证,但可以做到这一点。例如,如果您的用户经常与您的服务器位于不同的位置,那么 CDN 可以使您的内容更靠近他们。

如需了解详情,请参阅优化 TTFB 指南

资源加载延迟、LCP 运行缓慢的罪魁祸首是被忽视

如果 TTFB 可以改进,但任何改进都受物理特性的约束,那么资源加载延迟或许可以消除,实际上,仅受服务架构约束。

该子部分测量从收到 HTML 响应 (TTFB) 的第一个字节到浏览器开始请求 LCP 图片所用的时间。多年来,我们一直在关注下载 LCP 图片所需的时间,但我们经常忽略了在浏览器收到开始下载提示之前就浪费的时间。

对于 LCP 表现不佳的中位数网站,其等待开始下载 LCP 图片所用的时间几乎是实际下载 LCP 图片的四倍,在 TTFB 和图片请求之间等待 1.3 秒。这超过了 2.5 秒 LCP 预算的一半以上。

依赖项链是导致加载延迟时间较长的常见原因。较为简单的一点是,页面加载样式表,在浏览器完成布局后,系统会设置一个背景图片,该图片最终将成为 LCP。所有这些步骤都必须在浏览器确定开始下载 LCP 图片之前完成。

使用 HTTP Archive 公开抓取数据,其中记录了“发起者”从 HTML 文档到 LCP 图片的网络请求链,您可以看到请求链长度与 LCP 速度较慢之间有明确的关联。

<ph type="x-smartling-placeholder">
</ph> 直观呈现从属请求链与 LCP 之间的关系的图表。LCP 中间值从 2,150 毫秒(包含 0 个依赖请求)上升到 2,540 毫秒(有 1 个依赖请求)到 2,850 毫秒(有 2 个依赖请求) <ph type="x-smartling-placeholder">
</ph> 从属请求链与 LCP 之间的关系。

关键是要尽快让浏览器知道 LCP 是什么,这样浏览器就能开始加载,即使在页面布局中有可用位置之前也是如此。您可以使用一些工具完成此操作,例如在 HTML 中使用经典的 <img> 标记(这样预加载扫描器可以快速找到它并开始下载),或者使用 <link rel="preload"> 标记(或 HTTP 标头),以便标记不属于 <img> 的图片。

帮助浏览器确定要优先处理的资源也很重要。如果您的网页在网页加载期间发出了很多请求,这一点尤为重要,因为浏览器通常只有在其中许多资源都已加载且布局已加载完毕之后才会知道 LCP 元素是什么。使用 fetchpriority="high" 属性为可能的 LCP 元素添加注解(并确保避免使用 loading="lazy"),可让浏览器明确知道应立即开始加载资源。

阅读有关优化加载延迟的更多建议

渲染延迟

呈现延迟时间用于衡量从浏览器加载并准备就绪 LCP 图片开始的时间,但出于某种原因,图片在屏幕上显示时会有延迟。有时,这是一个耗时较长的任务,在图片准备就绪时阻塞主线程,而在其他情况下,这可能是显示隐藏元素的界面选择。

对于网络上的典型来源,呈现延迟似乎并不大,但在优化期间,有时您可以创建渲染延迟,让之前在其他子部分花费的时间占到。例如,如果网页开始预加载 LCP 图片以便快速加载,则不会再有很长的加载延迟,但如果网页本身尚未准备好显示图片(例如,如果网页本身尚未准备好显示图片(例如,从会阻止内容呈现的大型样式表或客户端渲染应用中必须完成其所有 JavaScript 的加载才能显示),则 LCP 会比它应该变慢,而且等待时间也会显示为呈现延迟。正因如此,在 LCP 方面,服务器端呈现或静态 HTML 通常具有优势。

如果您自己的内容受到影响,请参阅有关优化渲染延迟的更多建议

请检查所有这些子部分

很明显,要有效优化 LCP,开发者需要全面关注网页加载情况,而不仅仅是专注于优化图片。请每时每刻检查一次 LCP,因为目前改进的空间可能要大得多。

为了在字段中收集此类数据,web-vitals 库的归因 build 中会包含 LCP 子部分的计时。Chrome 用户体验报告 (CrUX) 尚未包含所有数据,但包含 TTFB 和 LCP 条目,因此是一个开始。我们希望将来在 CrUX 中包含这篇博文使用的数据,敬请关注更多相关新闻。

如需在本地测试 LCP 子部分,请尝试使用网页指标扩展程序本文中的 JavaScript 代码段。Lighthouse 还在其“Largest Contentful Paint 元素”中添加了细分。审核。您可以在开发者工具性能面板中查看更多 LCP 子部分建议(即将推出)。