Largest Contentful Paint (LCP) 是三个核心网页指标指标之一。它表示网页主要内容的加载速度,具体而言,即从用户开始加载网页到最大的图片或文本块在视口中呈现之间的时间。
为了提供良好的用户体验,网站在至少 75% 的网页访问中的 LCP 不得超过 2.5 秒。
有很多因素会影响浏览器加载和呈现网页的速度,其中任何因素的延迟都会对 LCP 产生重大影响。
很少通过快速修复网页的单个部分对 LCP 产生有意义的改进的情况很少见。为了改进 LCP,您必须了解整个加载过程,确保对整个过程中的每一步都进行优化。
本部分介绍了一种将 LCP 细分为最重要的子类别的方法,以及用于优化每个子类别的具体建议和最佳做法。
例如,以下可视化图表在典型网页加载的网络瀑布图上突出显示了这些资源,其中 LCP 元素需要渲染图片请求。
对于经过精心优化的网页,您希望 LCP 资源请求尽早开始加载,并且希望 LCP 元素在 LCP 资源加载完成后尽快呈现。为了直观呈现特定网页是否遵循此原则,您可以将总 LCP 时间细分为以下子类别:
首字节时间 (TTFB)
从用户开始加载页面到浏览器收到 HTML 文档响应的第一个字节所需的时间。
资源加载延迟
TTFB 与浏览器开始加载 LCP 资源之间的间隔时间。如果 LCP 元素不需要加载资源即可渲染(例如,如果该元素是使用系统字体渲染的文本节点),则此时间为 0。
资源加载时间
加载 LCP 资源本身所需的时间。如果 LCP 元素不需要加载资源即可渲染,则此时间为 0。
元素渲染延迟
从 LCP 资源加载完毕到 LCP 元素完全呈现所经过的时间。
每个网页的 LCP 均包含这四个子类别。它们之间没有间隙或重叠,加起来等于完整的 LCP 时间。
优化 LCP 时,尝试优化这些子类别会很有帮助。不过,您需要确保所有子类别都得到优化,因为某些优化会将在某一部分节省的时间转移到另一部分,而不是实际减少 LCP。
例如,在网络瀑布流示例中,通过更多压缩图片或切换到更优化的格式(例如 AVIF 或 WebP)来减小图片的文件大小,可以缩短资源加载时间,但无法改善 LCP,因为该时间将成为元素渲染延迟的一部分。这是因为 LCP 元素会处于隐藏状态,直到其关联的 JavaScript 加载完成,然后才会显示出来。
如需优化 LCP 的每个子类别,请务必了解在经过精心优化的网页上呈现这些子类别的理想细分是什么。
必须尽可能减少这两个涉及延迟的子类别。另外两个涉及网络请求,它们本身需要时间并且无法完全优化。
以下是理想化的 LCP 分布情况。
这些时间仅供参考,而不是严格规定。如果您的网页的 LCP 时间始终在 2.5 秒或更短时间内,那么细分情况看起来无关紧要。但是,如果延迟类别过长,则您无法达到 2.5 秒的目标。
我们建议您按照如下方式考虑 LCP 时间细分维度:
1、绝大部分 LCP 时间都必须用在加载 HTML 文档和 LCP 源代码上。
2、在 LCP 之前,如果这两项资源中有一项未加载,您就有机会改进。
现在,您已经了解了 LCP 子类别时间在经过精心优化的网页上的显示效果,接下来可以开始优化自己的网页了。
以下各部分介绍了针对各个类别进行优化的建议和最佳做法,从可能产生最大影响的优化开始。
消除资源加载延迟
此步骤的目的是确保 LCP 资源尽早开始加载。虽然从理论上说,最早可以立即加载资源的时间是 TTFB 之后,但实际上,浏览器在实际开始加载资源之前总是会有一段延迟。
推荐做法是确保 LCP 资源与网页加载第一个资源同时启动。
一般来说,有两个因素会影响 LCP 资源的加载速度:
1、发现资源时。
2、为资源指定的优先级。
在发现资源时进行优化
为确保您的 LCP 资源尽早开始加载,浏览器的预加载扫描程序必须在初始 HTML 文档响应中发现该资源。以下是可检测到的 LCP 资源的一些示例:
1、 元素,其 src 或 srcset 属性位于初始 HTML 标记中。
2、任何需要 CSS 背景图片的元素,前提是该图片已由 HTML 标记中的 (或使用 Link 标头)预加载。
3、一个文本节点,需要网页字体才能呈现,前提是该字体由 HTML 标记中的 (或使用 Link 标头)预加载。
以下是一些通过扫描 HTML 文档响应无法找到的 LCP 资源。在每种情况下,浏览器都必须运行脚本或应用样式表,然后才能发现并开始加载 LCP 资源,这需要等待网络请求完成。
1、使用 JavaScript 动态添加到网页的 。
2、使用会隐藏 src 或 srcset 属性(通常为 data-src 或 data-srcset)的 JavaScript 库延迟加载的任何元素。
3、任何需要 CSS 背景图片的元素。
为了消除不必要的资源加载延迟,您的 LCP 资源必须可从 HTML 源代码中发现。如果仅从外部 CSS 或 JavaScript 文件引用资源,则必须以较高的提取优先级预加载该 LCP 资源,例如:
<link rel="stylesheet" href="/path/to/styles.css">
<link rel="preload" fetchpriority="high" as="image" href="/path/to/hero-image.webp" type="image/webp">
即使可从 HTML 标记中找到 LCP 资源,它也可能不会尽早开始加载第一个资源。如果浏览器预加载扫描程序的优先级启发式算法未识别出相应资源重要,或者认为其他资源更重要,就可能会发生这种情况。
例如,如果您在 元素上设置了 loading="lazy",则可以使用 HTML 延迟 LCP 图片。使用延迟加载意味着,只有在布局确认图片位于视口中之后才会加载资源,而这通常会导致它延迟加载。
即使没有延迟加载,浏览器最初也不会以高优先级加载图片,因为它们不是阻塞渲染的资源。您可以使用 fetchpriority 属性提高资源的加载优先级,如下所示:
如果您认为某个 元素可能是网页的 LCP 元素,那么最好在该元素上设置 fetchpriority="high"。但是,为一两个以上的图片设置高优先级对降低 LCP 没有帮助。
您还可以降低可能在文档响应的早期阶段但因样式设置而不可见的图片(例如,轮播幻灯片中启动时不可见的图片)的优先级:
降低某些资源的优先级可以为需要更多资源的资源提供更多带宽,但要注意不要过度使用。请务必在开发者工具中检查资源优先级,并使用实验室和现场工具测试更改。
优化 LCP 资源优先级和发现时间后,网络瀑布流应如下所示,其中 LCP 资源与第一个资源同时开始:
要点:您的 LCP 资源可能不会尽早开始加载的另一个原因是,即使可以从 HTML 源代码中发现该资源,原因就是:如果资源托管在其他来源上,浏览器必须连接到该来源才能开始加载该资源。如有可能,我们建议将关键资源托管在与 HTML 文档资源相同的来源上,以便浏览器可以重复使用现有连接以节省时间。
此步骤的目的是确保 LCP 元素能够在其资源加载完毕后立即呈现,而不管何时呈现。
LCP 元素无法在其资源加载完毕后立即呈现的主要原因是呈现因某些其他原因而被阻塞:
由于 中的样式表或同步脚本仍在加载,整个网页已被阻止呈现。LCP 资源已加载完毕,但 LCP 元素尚未添加到 DOM 中,原因是它正在等待 JavaScript 代码加载。
相应元素被其他一些代码隐藏,例如尚未决定将用户放入哪个实验组的 A/B 测试库。主线程因长时间运行的任务而阻塞,渲染工作必须等待这些长时间运行的任务完成。以下部分介绍了如何解决导致不必要的元素渲染延迟的最常见原因。
减少或内嵌阻止呈现的样式表
从 HTML 标记加载的样式表会阻止系统呈现其后跟随的所有内容。这通常是件好事,因为这可以让样式表在其他元素加载之前生效。不过,如果样式表规模过大,以致于加载所用时间远远超过 LCP 资源,那么即使在 LCP 资源加载完毕后,它也会阻止呈现相应元素,如下例所示:
要解决此问题,您可以执行以下任一操作:
1、将该样式表内嵌到 HTML 中,以避免产生额外的网络请求;或者,
2、减小样式表的大小。
只有当样式表较小时,内嵌样式表才能有效降低 LCP。不过,如果样式表的加载时间比 LCP 资源长,则说明它可能过大,无法有效内嵌,因此我们建议您按照以下步骤来降低样式表的复杂性:
1、移除未使用的 CSS:使用 Chrome 开发者工具查找未使用的 CSS 规则,这些规则可能会被移除(或延迟)。
2、推迟非关键 CSS:将样式表拆分为用于初始网页加载的样式,然后拆分为可延迟加载的样式。
3、缩减 CSS 大小:对于关键样式,请务必尽可能减小其传输大小。
我们建议您使用 async 或 defer 属性将网页上的所有脚本设为异步。使用同步脚本几乎总是会影响性能。
但是,如果您有需要在网页加载时尽早运行的 JavaScript,则可以通过内嵌小型脚本来减少浏览器等待网络请求所花的时间,从而改进 LCP。
服务器端渲染 (SSR) 是在服务器上运行客户端应用逻辑,并使用完整的 HTML 标记响应 HTML 文档请求的过程。
SSR 可以通过以下方式帮助优化 LCP:
1、它可以让 HTML 源代码检测到您的资源,如消除资源加载延迟中所述。
2、它可防止您的网页需要完成额外的 JavaScript 请求才能呈现。
SSR 的主要缺点是需要额外的服务器处理时间,这可能会降低 TTFB 的速度。不过,这种权衡通常很值得,因为服务器处理时间由您控制,而用户的网络和设备功能则不在话下。
我们还建议您在构建步骤中(而不是按需)生成 HTML 页面,以获得更好的性能。这种做法称为静态网站生成 (SSG) 或预呈现。
即使您遵循了所有建议,并且 JavaScript 代码不会阻止渲染,也不负责渲染元素,它仍会导致 LCP 延迟。
最常见的原因是,当网页加载大型 JavaScript 文件时,浏览器需要一些时间来解析并执行其主线程上的代码。这意味着,即使 LCP 资源已完全下载,可能仍然必须等到不相关脚本执行完毕之后才能呈现。
所有浏览器都在主线程上渲染图片,这意味着阻塞主线程的任何因素也可能导致不必要的元素渲染延迟。因此,我们建议将一个大型 JavaScript 文件拆分为多个脚本文件,其中每个文件都可根据需要进行解析。
此步骤旨在减少浏览器将资源通过网络传输到用户设备所花的时间。一般来说,有以下几种方法可以实现此目的:
1、缩减资源大小。
2、减少资源需要的行程。
3、减少网络带宽争用。
4、完全消除网络时间。
5、缩减资源大小
LCP 资源通常是图片或网页字体。以下指南详细介绍了如何缩减这两者的大小:
1、提供最佳图片大小
2、使用新型图片格式
3、压缩图片
4、缩减网页字体大小
此外,您还可以通过在地理位置上尽可能靠近用户的位置来缩短加载时间。要做到这一点,最好的方法是使用内容分发网络 (CDN)。
事实上,图片 CDN 特别有用,因为它们既能缩短资源行程的距离,又能按照前文提到的策略减小资源的大小。
要点:图片 CDN 是缩短资源加载时间的绝佳方式。但是,使用第三方网域托管图片会产生额外的连接费用。虽然预先连接到原始来源可以减少一部分此类费用,但最好是从 HTML 文档所在的来源传送图片。为此,许多 CDN 都允许您将来自您的源站的请求代理到他们的源站。
此步骤的目的是尽快提供初始 HTML。此步骤排在最后,因为这通常是开发者控制力最弱的步骤。不过,这也是最重要的步骤之一,因为它会直接影响它之后的每一个步骤。在后端传送第一个字节内容之前,前端不会发生任何操作,因此您可以采取的旨在加快 TTFB 速度的任何操作都会改善所有其他负载指标。
对于如果网站本身速度很快,导致 TTFB 速度变慢的常见原因是访问者通过多次重定向(例如从广告或短链接访问)到达。始终尽可能减少访问者必须等待的重定向次数。
另一个常见原因是无法从 CDN 边缘服务器使用缓存的内容,这要求将所有请求都定向回源服务器。如果访问者使用唯一的网址参数进行分析,就可能会发生这种情况,即使他们没有返回不同的网页也是如此