4422 字
22 分钟
LCP
2026-02-12
2026-02-12
统计加载中...

LCP#

LCP(Largest Contentful Paint):视口内可见最大图片、文本或视频的渲染时间

一、LCP 的工作方式#

如何确定元素的大小?#

  • 为 LCP 报告的元素大小通常是指用户在视口中看到的大小。如果元素超出视口范围,或者元素的任何部分被剪裁或具有不可见的溢出,则这些部分不会计入元素的大小。
  • 对于已从固有大小调整大小的图片元素,系统会报告较小的可见大小或固有大小。
  • 对于文本元素,LCP 仅考虑可包含所有文本节点的最小矩形。
  • 对于所有元素,LCP 均不会考虑使用 CSS 应用的外边距、内边距或边框。

何时报告 LCP?#

网页通常分阶段加载,因此网页上最大的元素可能会发生变化。

为了处理这种潜在的变化,浏览器会在绘制第一帧后立即调度类型为 largest-contentful-paintPerformanceEntry,以标识最大的内容元素。但是,在渲染后续帧后,每当 Largest Contentful Element 发生变化时,它都会调度另一个 PerformanceEntry

只有在元素呈现并可供用户看到后,才能将其视为包含内容的最大元素。尚未加载的图片不计入“呈现”次数。在字体块期内,文本节点也不会使用 Web 字体。在这种情况下,系统可能会报告较小的元素为最大内容渲染时间元素,但一旦较大的元素完成渲染,系统就会创建另一个 PerformanceEntry

除了延迟加载的图片和字体之外,网页可能会在有新内容可用时向 DOM 添加新元素。如果其中任何新元素的大小大于之前最大的有内容元素,系统也会报告新的 PerformanceEntry

如果从视口中移除(甚至从 DOM 中移除)最大的内容元素,除非渲染出更大的元素,否则它仍然是最大的内容元素。

一旦用户与网页互动(通过点按、滚动或按键操作),浏览器就会停止报告新条目,因为用户互动通常会更改对用户可见的内容(这在滚动时尤其如此)。

二、优化 LCP#

测量方式与主要指标:

从用户开始加载网页到视口内渲染最大图片或文本块的时间

网站应力求将至少 75%(P75) 的网页访问的 LCP 控制在 2.5 秒或更短的时间内

LCP 细分#

如何确定 LCP 元素 在 Chrome 开发者工具的 performance 面板中左侧 LCP 细分-> 发现 lCP 请求,右侧瀑布图会展示具体的 lCP 资源,选中右键可以选择跳转到 network 面板查看 此演示界面显示的就是:

LCP 总时间分解为以下子部分:

第一字节时间 (TTFB)

从用户开始加载网页到浏览器收到 HTML 文档响应的第一个字节所用的时间。

资源加载延迟

TTFB 与浏览器开始加载 LCP 资源之间的时间。如果 LCP 元素不需要加载资源即可呈现(例如,如果该元素是使用系统字体呈现的文本节点),则此时间为 0。

资源加载时长

加载 LCP 资源本身所需的时间。如果 LCP 元素不需要加载资源即可呈现,则此时间为 0。

元素渲染延迟

从 LCP 资源完成加载到 LCP 元素完全渲染之间的时间。

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

选中 LCP 细分可以看到右侧瀑布图的标注

优化思路#

1. 消除_资源加载延迟_#

此步骤的目标是确保 LCP 资源尽早开始加载。LCP 资源应与该网页加载的第一个资源同时开始加载。换句话说,如果 LCP 资源开始加载的时间晚于第一个资源,则有改进空间。

在此网页上,LCP 资源在首先加载的样式表之后才开始加载。这方面还有提升空间。

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

  • 发现资源的时间。
  • 资源获得的优先级。

在发现资源时进行优化#

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

  • LCP 元素是 <img> 元素,并且其 srcsrcset 属性存在于初始 HTML 标记中。
  • LCP 元素需要 CSS 背景图片,但该图片是使用 HTML 标记中的 <link rel="preload">(或使用 Link 标头)预加载的。
  • LCP 元素是需要使用 Web 字体进行渲染的文本节点,并且该字体是使用 HTML 标记中的 <link rel="preload">(或使用 Link 标头)加载的。

以下是一些无法通过扫描 HTML 文档响应来发现 LCP 资源的情况:

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

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

为消除不必要的资源加载延迟,您的 LCP 资源应可从 HTML 源代码中发现。如果资源仅从外部 CSS 或 JavaScript 文件中引用,则应使用较高的提取优先级(fetchpriority=“high”)预加载 (rel=“preload”)LCP 资源

优化资源获得的优先级#

即使 LCP 资源可从 HTML 标记中发现,它_仍然_可能不会像第一个资源那样尽早开始加载。如果浏览器预加载扫描器的优先级启发法无法识别出相应资源的重要性,或者如果它确定其他资源更重要,则可能会发生这种情况。

例如,如果您在 <img> 元素上设置 loading="lazy",则可以使用 HTML 延迟 LCP 图片。使用延迟加载意味着,在布局确认图片位于视口中之前,资源不会加载,因此加载时间可能会比正常情况下晚。 即使没有延迟加载,浏览器也不会以最高优先级初始加载图片,因为它们不是会阻止渲染的资源。对于可以从更高优先级中受益的资源,您可以使用 fetchpriority 属性向浏览器提示哪些资源最重要

如果您认为某个 <img> 元素很可能是网页的 LCP 元素,最好为该元素设置 fetchpriority="high"。不过,如果将多个图片(超过一两个)设置为高优先级,则优先级设置对缩短 LCP 毫无帮助

您还可以降低文档响应中可能位于较早位置但因样式设置而不可见的图片的优先级

LCP 资源现在与样式表同时开始加载。

2. 消除_元素渲染延迟_#

此步骤的目标是确保 LCP 元素可在其资源完成加载(无论何时)后_立即_渲染。

LCP 元素_无法_在其资源完成加载后立即渲染的主要原因是,渲染因其他原因而被阻止

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

以下部分介绍了如何解决不必要的元素渲染延迟的最常见原因。

减少或内嵌阻塞渲染的样式表#

从 HTML 标记加载的样式表会阻止渲染其后的所有内容,这很好,因为您通常不希望渲染未设置样式的 HTML。不过,如果样式表过大,导致其加载时间明显长于 LCP 资源,那么即使 LCP 资源已完成加载,样式表也会阻止 LCP 元素渲染,如本例所示:

图片和样式表同时开始加载,但图片在样式表准备就绪之前无法呈现。

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

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

  • 移除未使用的 CSS:使用 Chrome 开发者工具查找未使用的 CSS 规则,这些规则可以移除(或延迟加载)。

如何检测未使用的 CSS

  1. 在 DevTools 处于焦点的情况下,按 Command+Shift+P(Mac)或 Control+Shift+P(Windows、Linux、ChromeOS)以打开“命令”菜单。
  2. 开始输入 coverage显示覆盖范围
  3. 选择显示覆盖率。系统随即会显示“Coverage”(覆盖率)标签页。
  4. Reload(重新加载)。 网页会重新加载,Coverage(覆盖率)标签页会简要显示浏览器加载的每个文件中使用的 CSS(和 JavaScript)数量。 绿色代表已使用的 CSS。红色代表未使用的 CSS。
  5. 点击某个 CSS 文件,即可在上述预览中逐行查看该文件使用的 CSS。 在屏幕截图中,devsite-google-blue.css 的 55 到 57 行和 65 到 67 行未使用,而 59 到 63 行已使用。

vite-plugin-critical TODO: 补充实战截图

BrotliCDN

延后或内嵌会阻止渲染的 JavaScript#

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

Vite 构建时,默认生成的 index.html 中会包含 <script type="module" src="/src/main.js">,该脚本默认带有 type="module",浏览器对模块脚本默认采用类似 defer 的行为(不阻塞 HTML 解析,按顺序执行)。

使用服务器端渲染#

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

从优化 LCP 的角度来看,SSR 有两个主要优势:

  • 您的图片资源将可从 HTML 源代码中发现。
  • 您的网页内容无需额外的 JavaScript 请求即可完成渲染。

SSR 的主要缺点是需要额外的服务器处理时间,这可能会减慢 TTFB。不过,这种权衡通常是值得的,因为服务器处理时间在您的控制范围内,而用户的网络和设备功能不在您的控制范围内。

与 SSR 类似的选项称为静态网站生成 (SSG) 或预呈现。这是在构建步骤中(而不是按需)生成 HTML 页面的过程。如果您的架构支持预渲染,那么从性能角度来看,预渲染通常是更好的选择。

拆分长任务#

即使您已遵循之前的建议,并且您的 JavaScript 代码不会阻塞渲染,也不会负责渲染元素,但它仍可能会延迟 LCP。

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

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

3. 缩短资源加载时长#

此步骤的目标是减少通过网络将资源字节传输到用户设备所花费的时间。一般来说,您可以通过以下四种方式来完成此操作:

  • 缩减资源的大小。
  • 缩短资源必须移动的距离。
  • 减少对网络带宽的争用。
  • 完全消除网络时间。

缩减资源的大小#

网页的 LCP 资源(如果有)将是图片或 Web 字体。以下指南详细介绍了如何缩减以下两项的大小:

vite-plugin-image-optimizerCDN

AVIFWebP

缩短资源必须经过的距离#

除了减小资源大小之外,您还可以通过让服务器尽可能靠近用户来缩短加载时间。实现这一目标的最佳方式是使用内容分发网络 (CDN)。

图片 CDN 尤其有用,因为它们不仅可以缩短资源传输距离,还可以减小资源大小,自动为您实现之前的所有大小缩减建议。

减少对网络带宽的争用#

即使您已减小资源的大小和传输距离,如果您同时加载许多其他资源,资源仍可能需要很长时间才能加载完毕。此问题称为_网络争用_。

如果您为 LCP 资源指定了较高的 fetchpriority 并尽早开始加载该资源,那么浏览器会尽最大努力防止低优先级资源与该资源竞争。不过,如果您加载了许多具有较高 fetchpriority 的资源,或者只是加载了大量资源,那么这可能会影响 LCP 资源的加载速度。

完全消除网络时间#

缩短资源加载时长的最佳方法是从流程中完全移除网络。如果您使用高效的 cache-control 政策来提供资源,那么第二次请求这些资源的访问者将从缓存中获取这些资源,从而使_资源加载时长_基本上为零!

如果 LCP 资源是 Web 字体,除了减小 Web 字体大小之外,您还应考虑是否需要在加载 Web 字体资源时阻止渲染。如果您将 font-display 值设置为 autoblock 以外的任何值,则文本将在加载期间始终可见,并且 LCP 不会因额外的网络请求而被阻塞。

CSS 解析 → 发现 @font-face → 存入字体表 ↓ 渲染树构建 → 确定元素所需字体 ↓ 检查本地字体 (local) ↓ 若不存在 → 遍历 src 列表 ↓ 检查 format()支持 → 发起下载 ↓ 下载完成 → 解析字体 → 更新渲染

最后,如果 LCP 资源较小,则可以考虑将资源内嵌为 data 网址,这样也可以消除额外的网络请求。不过,使用数据网址需要注意一些事项,因为这样一来,资源就无法缓存,并且在某些情况下,由于额外的解码成本,可能会导致渲染延迟时间更长。

Base64 编码的文件通常比单纯下载文件大 20%-30%——这取决于文件大小,可能使加载页面的延迟成本过高。其次,一旦文件被 Base64 编码并嵌入到 HTML 或 CSS 中,它们就变成了渲染阻挡——因为必须先下载这些文件,CSS 才能被渲染和显示

4. 缩短_加载第一个字节所需时间_#

此步骤的目标是尽快提供初始 HTML。此步骤之所以列在最后,是因为开发者通常对此步骤的控制权最少。不过,这也是最重要的步骤之一,因为它会直接影响后续的每个步骤。在后端传送第一个内容字节之前,前端不会发生任何事情,因此,您采取的任何加快 TTFB 的措施都会改善其他所有加载指标。

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

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

摘要#

LCP 非常复杂,其时间可能会受到多种因素的影响。但如果您认为优化 LCP 主要在于优化 LCP 资源的加载,那么事情就会变得简单得多。

概括来讲,优化 LCP 可归纳为四个步骤:

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