优化 Largest Contentful Paint

关于如何分解 LCP 并确定需要改进的关键领域的分步指南。

Largest Contentful Paint (LCP) 是三个核心网页指标指标之一,表示网页主要内容的加载速度。具体来说,LCP 衡量从用户开始加载网页到最大的图片或文本块在视口中呈现之间的时间。

为了提供良好的用户体验,网站应努力在至少 75% 的网页访问中将 LCP 控制在 2.5 秒以内。

良好 LCP 值为 2.5 秒或更短,不良值大于 4.0 秒,两者之间的任何值都需要改进
良好的 LCP 值为 2.5 秒或更短。

有很多因素会影响浏览器加载和呈现网页的速度,其中任何因素的延迟都会对 LCP 产生重大影响。

通过快速修复网页的单个部分,可对 LCP 产生实质性改善的情况很少见。为了改进 LCP,您必须了解整个加载过程,并确保整个过程中的每一步都得到优化。

了解 LCP 指标

在优化 LCP 之前,开发者应设法了解自己是否存在 LCP 问题,以及此类问题的严重程度。

LCP 可以使用多种工具进行测量,但并非所有工具都以相同的方式测量 LCP。要了解真实用户的 LCP,我们应该查看真实用户的体验,而不是 Lighthouse 或本地测试等基于实验室的工具显示的情况。这些基于实验室的工具可提供大量信息,方便您解释并帮助您改进 LCP,但请注意,仅实验室测试可能无法完全代表您的实际用户体验。

您可以通过网站上安装的实时用户监控 (RUM) 工具显示基于真实用户的 LCP 数据,也可以使用 Chrome 用户体验报告 (CrUX) 从数百万网站的真实 Chrome 用户那里收集匿名数据。

使用 PageSpeed Insights CrUX LCP 数据

利用 PageSpeed Insights,您可以在顶部标有了解真实用户的体验的部分中访问 CrUX 数据。您可在底部标记为诊断性能问题的部分中找到更详细的实验室数据。如果您的网站有 CrUX 数据,请始终先着重分析真实用户数据。

PageSpeed Insights 会显示 CrUX 数据
CrUX 数据会显示在 PageSpeed Insights 中。

PageSpeed Insights 最多可显示四种不同的 CrUX 数据:

  • 此网址移动数据
  • 此网址桌面设备数据
  • 整个源站移动流量
  • 整个 Origin桌面设备数据

您可以在此部分顶部和右上角的控件中进行切换。如果网址没有足够的数据,无法在网址级别显示,但确实有源数据,PageSpeed Insights 会始终显示源数据。

PageSpeed Insights 会回退到无法获取网址级数据的原始级数据
如果 PageSpeed Insights 没有网址级数据,会显示源站级数据。

整个来源的 LCP 可能与单个网页的 LCP 有很大差异,具体取决于相应网页上的 LCP 加载方式与该来源上的其他网页的加载方式相比如何。此外,访问者浏览这些网页的方式也会影响该排名。首页往往会被新用户访问,因此经常会进入“冷”加载状态,没有任何缓存内容,加载速度往往是网站上最慢的网页。

查看 4 种不同类别的 CrUX 数据有助于您了解是 LCP 问题是针对此网页,还是更常见的网站级问题。同样,它也可以显示哪些设备类型存在 LCP 问题。

使用 PageSpeed Insights CrUX 补充指标

希望优化 LCP 的公司还应该使用首次内容绘制 (FCP)首字节时间 (TTFB) 计时,这两个指标都是很好的诊断指标,可提供关于 LCP 的宝贵数据洞见。

TTFB 是指访问者从开始导航到网页(例如,点击链接)直到收到 HTML 文档的前几个字节的时间。较高的 TTFB 可能使实现 2.5 秒的 LCP 变得具有挑战性,甚至不可能实现。

多个服务器重定向、访问者位置远离最近的网站服务器、访问者网络状况不佳或因查询参数而无法使用缓存内容都可能导致 TTFB 高。

网页开始呈现后,系统可能会先进行初始绘制(例如背景颜色),之后再显示一些内容(例如网站标题)。初始内容的外观通过 FCP 来衡量。FCP 和其他指标之间的增量可能非常有意义。

TTFB 和 FCP 之间出现较大的增量,可能表示浏览器需要下载大量阻塞渲染的资源。这也表明网站必须完成大量工作才能渲染任何有意义的内容,这也是一个典型的迹象,表示网站非常依赖客户端渲染。

FCP 和 LCP 之间存在较大差异,表示 LCP 资源无法立即供浏览器进行优先级排序(例如,由 JavaScript 管理的文本或图片,而非初始 HTML 中可用),或者浏览器在显示 LCP 内容之前已完成其他工作。

使用 PageSpeed Insights Lighthouse 数据

PageSpeed Insights 的 Lighthouse 部分提供了一些有关如何改进 LCP 的指南,但您应先检查提供的 LCP 是否与 CrUX 提供的真实用户数据大致一致。如果 Lighthouse 和 CrUX 有分歧,那么 CrUX 可能会更准确地反映您的用户体验。请确保您的 CrUX 数据适用于您的网页,而不是完整来源,然后再对其执行操作。

如果 Lighthouse 和 CrUX 显示需要改进的 LCP 值,则 Lighthouse 部分可以就如何改进 LCP 提供有价值的指导。使用 LCP 过滤条件仅显示与 LCP 相关的审核,如下所示:

Lighthouse LCP 机会和诊断
Lighthouse 诊断信息和有关改进 LCP 的建议。

除了优化建议之外,诊断信息还可以提供更多信息,帮助您诊断问题。Largest Contentful Paint 元素诊断会详细列出构成 LCP 的各个时间时间:

Lighthouse LCP 阶段
Lighthouse 对 LCP 元素的细分。

接下来,我们将深入了解这些子部分。

LCP 细分

当 PageSpeed Insights 无法告诉您如何改进该指标时,针对 LCP 进行优化可能会是一项更为复杂的任务。对于复杂的任务,通常最好将它们分解为更容易管理的小任务,并分别处理每个任务。

本部分介绍了如何将 LCP 细分为最关键的子部分,然后针对如何优化各个部分提供具体建议和最佳做法。

大多数网页加载通常都会包含大量网络请求,但为了找出提升 LCP 的机会,建议您先只查看以下两个请求:

  1. 初始 HTML 文档
  2. LCP 资源(如果适用)

虽然网页上的其他请求可能会影响 LCP,但这两个请求(特别是 LCP 资源开始和结束时间的时间)会显示您的网页是否针对 LCP 进行了优化。

要确定 LCP 资源,您可以使用开发者工具(例如上面讨论的 PageSpeed Insights、Chrome 开发者工具WebPageTest)确定 LCP 元素。在这里,您可以匹配由该网页加载的所有资源的广告网络广告瀑布流中该元素加载的网址(同样适用,如果适用)。

例如,以下可视化图表在典型网页加载的网络瀑布图上突出显示了这些资源,其中 LCP 元素需要图片请求才能呈现。

突出显示 HTML 和 LCP 资源的广告联盟瀑布流
瀑布图,显示了网页 HTML 的加载时间以及 LCP 所需的资源。

对于经过精心优化的网页,您应尽早开始加载 LCP 资源请求,并且希望 LCP 元素在 LCP 资源加载完成后尽快呈现。为了直观地了解特定网页是否遵循了这一原则,您可以将总 LCP 时间细分为以下几部分:

首字节时间 (TTFB)
从用户开始加载页面到浏览器收到 HTML 文档响应的第一个字节所需的时间。
资源加载延迟
TTFB 与浏览器开始加载 LCP 资源之间的间隔时间。如果 LCP 元素不需要加载资源即可渲染(例如,如果该元素是使用系统字体渲染的文本节点),则此时间为 0。
资源加载时长
加载 LCP 资源本身所需的时间。如果 LCP 元素不需要加载资源即可渲染,则此时间为 0。
元素渲染延迟
从 LCP 资源加载完毕到 LCP 元素完全呈现所经过的时间。

每个网页的 LCP 均包含这四个子类别。它们之间没有间隙或重叠,加起来等于完整的 LCP 时间。

显示四个子类别的 LCP 细分
同一个瀑布图,时间轴上叠加了四个 LCP 子类别。

每个网页的 LCP 值都可以细分为以下四个子部分。它们之间没有重叠或间隔。它们的总和等于完整的 LCP 时间。

优化 LCP 时,尝试单独优化这些子部分会很有帮助。但同时请注意,您需要优化所有这些设置。在某些情况下,应用于一个部分的优化并不会改善 LCP,只会将节省的时间转移到另一个部分。

例如,在之前的网络瀑布流中,如果您通过进一步压缩图片或切换到更理想的格式(例如 AVIF 或 WebP)来减小图片的文件大小,虽然可以缩短资源加载时长,但实际上并不会改善 LCP,因为时间只会转移到“元素渲染延迟”子部分:

与之前所示的 LCP 细分一样,资源加载时长子类别缩短了,但总体 LCP 时间保持不变。
缩短资源加载时长会增加元素渲染延迟时间,而不会降低 LCP。

发生这种情况的原因是,在该网页上,LCP 元素会处于隐藏状态,直到 JavaScript 代码加载完成,然后才会立即显示所有内容。

此示例有助于说明,为了获得最佳 LCP 结果,您需要优化所有这些子部分。

最佳子部分时间

为了优化 LCP 的每个子部分,请务必了解在经过精心优化的网页上呈现的这些子部分理想的情况是怎样的。

四个子部分中,有两个在名称中包含“delay”一词。这表示您希望使这些时间尽可能接近零。其他两个部分涉及网络请求,从本质上来讲,请求需要一些时间。

LCP 子部分 LCP 占比 (%)
加载第一个字节所需时间 ~40%
资源加载延迟 < 10%
资源加载时长 ~40%
元素渲染延迟 < 10%
总计 100%

请注意,这些时间细分维度仅作指导原则,而非严格的规定。如果网页上的 LCP 时间始终在 2.5 秒以内,那么相对比例无关紧要。但是,如果您在任一“延迟”部分花费了大量不必要的时间,那么您就很难一直达到 2.5 秒的目标

以下列出了 LCP 时间明细的好方法:

  • 绝大部分 LCP 时间都应用在加载 HTML 文档和 LCP 源代码上。
  • 在 LCP 之前,如果这两种资源中有一项未加载,就意味着有改进的机会

如何优化各个部分

现在,您已经了解了每个 LCP 子部分时间应如何在经过精心优化的网页上细分,接下来就可以开始优化您自己的网页了。

接下来的四部分将介绍如何优化各个部分的建议和最佳做法。系统会按顺序展示这些优化目标,从可能产生最大影响的优化开始。

1. 消除资源加载延迟

此步骤的目的是确保 LCP 资源尽早开始加载。虽然从理论上讲,资源最早可以在 TTFB 之后立即开始加载,但实际上,浏览器在实际开始加载资源之前总是会有一些延迟。

推荐做法是,LCP 资源应在该网页首次加载资源的同时开始加载。换句话说,如果 LCP 资源开始加载的时间晚于第一个资源,则有改进空间。

网络瀑布流示意图,显示了在第一个资源之后启动的 LCP 资源,显示了改进机会
在此页面上,最先加载的样式表之后,LCP 资源才开始加载。这方面有改进的空间。

一般来说,有两个因素会影响 LCP 资源的加载速度:

  • 发现资源时。
  • 为资源指定的优先级。

在发现资源时进行优化

为了确保您的 LCP 资源尽早开始加载,请务必确保浏览器的预加载扫描程序能够在初始 HTML 文档响应中发现该资源。例如,在以下情况下,浏览器可以通过扫描 HTML 文档响应来发现 LCP 资源:

  • LCP 元素是 <img> 元素,其 srcsrcset 属性存在于初始 HTML 标记中。
  • LCP 元素需要 CSS 背景图片,但该图片已使用 HTML 标记中的 <link rel="preload">(或使用 Link 标头)预加载。
  • LCP 元素是一个需要网页字体才能呈现的文本节点,系统会使用 HTML 标记中的 <link rel="preload">(或使用 Link 标头)加载字体。

下面是无法通过扫描 HTML 文档响应找到 LCP 资源的一些示例:

  • LCP 元素是使用 JavaScript 动态添加到网页的 <img>
  • LCP 元素使用会隐藏其 srcsrcset 属性(通常显示为 data-srcdata-srcset)的 JavaScript 库进行延迟加载。
  • LCP 元素需要 CSS 背景图片。

在每种情况下,浏览器都需要先运行脚本或应用样式表(通常需要等待网络请求完成),然后才能发现 LCP 资源并开始加载它。这永远不是最佳选择。

为了消除不必要的资源加载延迟,您的 LCP 资源应能从 HTML 源代码中发现。如果仅从外部 CSS 或 JavaScript 文件引用资源,则应以较高的提取优先级预加载该 LCP 资源,例如:

<!-- Load the stylesheet that will reference the LCP image. -->
<link rel="stylesheet" href="/path/to/styles.css">

<!-- Preload the LCP image with a high fetchpriority so it starts loading with the stylesheet. -->
<link rel="preload" fetchpriority="high" as="image" href="/path/to/hero-image.webp" type="image/webp">

优化为资源指定的优先级

即使可从 HTML 标记中找到 LCP 资源,它也可能无法尽早开始加载第一个资源。如果浏览器预加载扫描程序的优先级启发式算法未识别出相应资源重要,或者认为其他资源更重要,就可能会发生这种情况。

例如,如果您在 <img> 元素上设置 loading="lazy",则可以使用 HTML 延迟 LCP 图片。使用延迟加载意味着,在布局确认图片位于视口内之前不会加载资源,因此开始加载的时间可能会晚于预期时间。

即使没有延迟加载,浏览器也不会最初以最高优先级加载图片,因为它们不是阻塞渲染的资源。您可以使用 fetchpriority 属性来提示浏览器哪些资源最重要,这些资源将从较高的优先级中受益:

<img fetchpriority="high" src="/path/to/hero-image.webp">

如果您认为某个 <img> 元素可能是网页的 LCP 元素,那么最好在该元素上设置 fetchpriority="high"。但是,为一两个以上的图片设置高优先级会使优先级设置对降低 LCP 没有帮助。

对于可能在文档响应的早期阶段但因样式设置而不可见的图片(例如,轮播幻灯片中启动时不可见的图片),您也可以降低其优先级:

<img fetchpriority="low" src="/path/to/carousel-slide-3.webp">

降低某些资源的优先级可以为需要更多资源的资源提供更多带宽,但要谨慎。请务必在开发者工具中检查资源优先级,并使用实验室和现场工具测试更改。

优化 LCP 资源优先级和发现时间后,您的网络瀑布流应如下所示(LCP 资源与第一个资源同时开始):

显示 LCP 资源现在与第一个资源同时启动的网络瀑布图
现在,LCP 资源会与样式表同时开始加载。

2. 消除元素渲染延迟

这一步的目标是确保 LCP 元素能够在其资源加载完毕后立即呈现,而不管何时呈现。

LCP 元素无法在其资源加载完毕后立即呈现的主要原因是呈现因其他原因而被阻塞

  • 由于 <head> 中的样式表或同步脚本仍在加载,整个网页已被阻止呈现。
  • LCP 资源已加载完毕,但 LCP 元素尚未添加到 DOM 中(正在等待一些 JavaScript 代码加载完毕)。
  • 此元素正被其他一些代码(例如仍在确定用户应参与的实验的 A/B 测试库)隐藏。
  • 主线程因长时间运行的任务而阻塞,渲染工作需要等待这些耗时较长的任务完成。

下面几部分将说明如何解决导致不必要的元素渲染延迟的最常见原因。

减少或内嵌阻止呈现的样式表

从 HTML 标记加载的样式表会阻止其后面的所有内容的呈现,这是个好现象,因为您通常不希望呈现没有样式的 HTML。不过,如果样式表规模过大,以致于加载所用时间远远超过 LCP 资源,则会阻止 LCP 元素呈现,即使在其资源加载完毕后也是如此,如下例所示:

一个网络瀑布图,其中显示了一个大型 CSS 文件阻止渲染 LCP 元素,因为加载时间比 LCP 资源长
图片和样式表同时开始加载,但在样式表准备就绪后,图片无法呈现。

要解决此问题,您有以下几种选择:

  • 将该样式表内嵌到 HTML 中,以避免产生额外的网络请求;或者,
  • 减小样式表的大小。

一般来说,只有在样式表较小时,才建议使用内嵌样式表,因为 HTML 中的内嵌内容无法从后续网页加载中获益。如果样式表太大,加载时间比 LCP 资源长,则不太可能适合使用内嵌。

在大多数情况下,要确保样式表不会阻止 LCP 元素渲染,最佳方法是缩减其大小,使其小于 LCP 资源。这应确保这不会成为大多数访问的瓶颈。

以下是缩减样式表大小的一些建议:

  • 移除未使用的 CSS:使用 Chrome 开发者工具查找未使用的 CSS 规则,这些规则可能会被移除(或延迟)。
  • 推迟非关键 CSS:将您的样式表拆分为初始网页加载所需的样式,然后拆分为可延迟加载的样式。
  • 缩减 CSS 大小:对于关键的样式,请务必尽可能减小其传输大小

延迟或内嵌阻止呈现的 JavaScript

几乎从来没有必要将同步脚本(不含 asyncdefer 属性的脚本)添加到网页的 <head> 中,而且这样做几乎总是会对性能产生负面影响。

如果 JavaScript 代码需要在网页加载时尽早运行,最好将其内嵌,以免在等待其他网络请求时延迟呈现。不过,与样式表一样,您应只内嵌非常小的脚本。

错误做法
<head>
  <script src="/path/to/main.js"></script>
</head>
正确做法
<head>
  <script>
    // Inline script contents directly in the HTML.
    // IMPORTANT: only do this for very small scripts.
  </script>
</head>

使用服务器端渲染

服务器端呈现 (SSR) 是在服务器上运行客户端应用逻辑,并使用完整 HTML 标记响应 HTML 文档请求的过程。

从优化 LCP 的角度来看,SSR 有两大优势:

  • 您的图片资源将可以从 HTML 源代码中找到(如前面的第 1 步中所述)。
  • 您的网页内容无需额外的 JavaScript 请求就能完成呈现。

SSR 的主要缺点是需要额外的服务器处理时间,这可能会降低 TTFB 的速度。不过,这种权衡通常还是值得的,因为服务器处理时间由您控制,而用户的网络和设备功能则不在话下。

与 SSR 类似的选项称为静态网站生成 (SSG) 或预呈现。这是在构建步骤中生成 HTML 网页的过程,而不是按需生成。如果您的架构可以进行预渲染,则它通常是一种更好的性能选择。

拆分长任务

即使您遵循了前面的建议,并且 JavaScript 代码既不会阻止呈现,也不负责呈现元素,它仍可能会延迟 LCP。

出现此错误的最常见原因是网页加载了大型 JavaScript 文件,而这些文件需要在浏览器的主线程上解析和执行。这意味着,即使图片资源已完全下载,可能仍然需要等到不相关脚本执行完毕后才能渲染。

目前的所有浏览器都在主线程上渲染图片,这意味着阻塞主线程的任何因素也可能会导致不必要的元素渲染延迟

3. 缩短资源加载时长

此步骤旨在减少通过网络将资源的字节传输到用户设备所花费的时间。一般来说,有以下三种方法可以实现此目的:

  • 缩减资源大小。
  • 减少资源需要的行程。
  • 减少网络带宽争用。
  • 完全消除网络时间。

缩减资源大小

网页(如果有)的 LCP 资源可以是图片,也可以是网页字体。以下指南详细介绍了如何缩减这两者的大小:

减少资源需要的行程距离

除了缩减资源的大小之外,您还可以通过使服务器在地理位置上尽可能靠近用户来减少加载时间。最好的方法是使用内容分发网络 (CDN)。

图片 CDN 尤其有用,因为它们不仅会减少资源需要行进的距离,而且通常还会缩减资源的大小 - 系统会自动为您采纳之前提供的所有缩减大小建议。

减少网络带宽争用

即使您缩减了资源的大小并缩短了行程距离,但如果您同时加载许多其他资源,也可能需要很长时间才能加载资源。此问题称为网络争用

如果您为 LCP 资源指定了fetchpriority尽快开始加载它,则浏览器会尽最大努力阻止优先级较低的资源与其竞争。不过,如果您加载许多具有较高 fetchpriority 的资源,或者通常只是加载大量资源,则可能会影响 LCP 资源的加载速度。

完全消除网络使用时间

缩短资源加载时长的最佳方法是从进程中完全消除网络。如果您采用高效的缓存控制政策来传送资源,那么第二次请求这些资源的访问者将从缓存提供这些资源,从而使资源加载时长基本上为零!

如果您的 LCP 资源是一种网页字体,那么除了缩减网页字体大小之外,您还应考虑是否需要在加载网页字体资源时阻止呈现。如果您将 font-display 值设为除 autoblock 以外的任何其他值,文本将始终在加载期间显示,并且系统不会在收到其他网络请求时屏蔽 LCP。

最后,如果 LCP 资源较小,可以将资源内嵌为数据网址,这样也可以省去额外的网络请求。不过,使用数据网址时需要注意,因为资源无法缓存,并且在某些情况下,还会因额外的解码成本而延长呈现延迟时间。

4. 缩短到第一个字节所用的时间

此步骤的目的是尽快提供初始 HTML。这一步排在最后,因为开发者通常对这个步骤的控制力最弱。不过,这也是最重要的步骤之一,因为它会直接影响它之后的每一个步骤。在后端传送第一字节内容之前,前端不会发生任何操作,因此您可以采取的方法来加快 TTFB 的加载速度,这也会提升所有其他负载指标。

对于速度较快的网站,TTFB 速度变慢的常见原因是访问者通过多次重定向(例如通过广告或短链接)进行访问。始终尽可能减少访问者必须等待的重定向次数。

另一个常见原因是无法从 CDN 边缘服务器使用缓存的内容,并且所有请求都必须直接定向回源服务器。如果访问者使用唯一网址参数进行分析,就可能会发生这种情况,即使这些参数没有返回不同的网页也是如此。

如需获得有关如何优化 TTFB 的具体指导,请参阅优化 TTFB 指南

监控 JavaScript 中的 LCP 细分

您可以通过以下性能 API 组合,在 JavaScript 中查看前面讨论的所有 LCP 子部分的时间信息:

在 JavaScript 中计算这些时间值的好处是,您可以将它们发送给分析提供程序或将它们记录到开发者工具中,以帮助进行调试和优化。

例如,以下屏幕截图使用 User Timing API 中的 performance.measure() 方法向 Chrome 开发者工具“性能”面板中的“计时”轨道添加栏。

Chrome 开发者工具中显示的 LCP 子类别的用户计时指标
“时间”轨道显示 LCP 子类别的时间轴。

与“网络”和“主线程”轨道一起查看时,“时间”轨道中的可视化功能尤为有用,因为您可以一目了然地查看在这些时间范围内网页上发生的其他情况。

除了在时间跟踪中直观呈现 LCP 子部分之外,您还可以使用 JavaScript 计算每个子部分占总 LCP 时间的百分比。根据这些信息,您可以确定您的网页是否符合上文所述的建议的百分比细分

此屏幕截图显示的示例记录了每个 LCP 子部分的总时间,及其占到控制台总 LCP 时间的百分比。

输出到控制台的 LCP 子类别时间及其占 LCP 的百分比
LCP 子类别的时间和百分比。

这两个可视化图表是使用以下代码创建的:

const LCP_SUB_PARTS = [
  'Time to first byte',
  'Resource load delay',
  'Resource load duration',
  'Element render delay',
];

new PerformanceObserver((list) => {
  const lcpEntry = list.getEntries().at(-1);
  const navEntry = performance.getEntriesByType('navigation')[0];
  const lcpResEntry = performance
    .getEntriesByType('resource')
    .filter((e) => e.name === lcpEntry.url)[0];

  // Ignore LCP entries that aren't images to reduce DevTools noise.
  // Comment this line out if you want to include text entries.
  if (!lcpEntry.url) return;

  // Compute the start and end times of each LCP sub-part.
  // WARNING! If your LCP resource is loaded cross-origin, make sure to add
  // the `Timing-Allow-Origin` (TAO) header to get the most accurate results.
  const ttfb = navEntry.responseStart;
  const lcpRequestStart = Math.max(
    ttfb,
    // Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
    lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0
  );
  const lcpResponseEnd = Math.max(
    lcpRequestStart,
    lcpResEntry ? lcpResEntry.responseEnd : 0
  );
  const lcpRenderTime = Math.max(
    lcpResponseEnd,
    // Use LCP startTime (the final LCP time) because there are sometimes
    // slight differences between loadTime/renderTime and startTime
    // due to rounding precision.
    lcpEntry ? lcpEntry.startTime : 0
  );

  // Clear previous measures before making new ones.
  // Note: due to a bug, this doesn't work in Chrome DevTools.
  LCP_SUB_PARTS.forEach((part) => performance.clearMeasures(part));

  // Create measures for each LCP sub-part for easier
  // visualization in the Chrome DevTools Performance panel.
  const lcpSubPartMeasures = [
    performance.measure(LCP_SUB_PARTS[0], {
      start: 0,
      end: ttfb,
    }),
    performance.measure(LCP_SUB_PARTS[1], {
      start: ttfb,
      end: lcpRequestStart,
    }),
    performance.measure(LCP_SUB_PARTS[2], {
      start: lcpRequestStart,
      end: lcpResponseEnd,
    }),
    performance.measure(LCP_SUB_PARTS[3], {
      start: lcpResponseEnd,
      end: lcpRenderTime,
    }),
  ];

  // Log helpful debug information to the console.
  console.log('LCP value: ', lcpRenderTime);
  console.log('LCP element: ', lcpEntry.element, lcpEntry.url);
  console.table(
    lcpSubPartMeasures.map((measure) => ({
      'LCP sub-part': measure.name,
      'Time (ms)': measure.duration,
      '% of LCP': `${
        Math.round((1000 * measure.duration) / lcpRenderTime) / 10
      }%`,
    }))
  );
}).observe({type: 'largest-contentful-paint', buffered: true});

您可以按原样使用此代码进行本地调试,也可以对其进行修改以将相关数据发送给分析提供商,以便更好地了解您网页上针对真实用户的 LCP 明细。

使用 Web Vitals 扩展程序监控 LCP 细分

Web Vitals 扩展程序在控制台中记录 LCP 时间、LCP 元素和这四个子部分,以便您轻松查看细分数据。

Web Vitals 扩展程序的控制台日志记录屏幕截图,其中显示了 LCP 子部分计时
Web Vitals 扩展程序的 Console 面板会显示 LCP 细分数据。

摘要

LCP 很复杂,其时间可能会受多种因素影响。但是,如果您认为优化 LCP 主要是为了优化 LCP 资源的负载,则可以大幅简化相关工作。

概括来讲,优化 LCP 可以总结为以下四个步骤:

  1. 确保 LCP 资源尽早开始加载。
  2. 确保 LCP 元素可在其资源完成加载后立即渲染。
  3. 在不牺牲质量的情况下,尽可能缩短 LCP 资源的加载时间。
  4. 尽快提供初始 HTML 文档。

如果您能够在网页上按照这些步骤操作,那么您应该确信自己向用户提供了最佳的加载体验,并且您应该会在真实的 LCP 得分中看到这一点。