改进核心网页指标的最有效方法

多年来,网络社区积累了丰富的网络性能优化知识。虽然任何一项优化都可以提升许多网站的性能,但如果同时进行所有优化,可能会让人感到不知所措。实际上,只有部分优化适用于任何给定的网站。

除非您是 Web 性能方面的专业人士,否则可能很难确定哪些优化措施对您的网站影响最大。您可能没有时间全部完成,因此请务必问自己:您可以选择哪些最具影响力的优化措施来提升用户体验?

关于性能优化,真相是:您不能仅根据技术优势来评判优化效果。您还需要考虑人力和组织因素,这些因素会影响您实现任何给定优化的可能性。从理论上讲,某些性能改进可能具有巨大影响,但在现实中,很少有开发者有时间或资源来实现这些改进。另一方面,有些效果最佳实践可能影响巨大,但几乎所有人都在遵循。本指南介绍了可实现以下目标的 Web 性能优化措施:

  • 产生最大的现实影响
  • 与大多数网站相关且适用
  • 大多数开发者都能实现

总的来说,这些是最切实有效的方法,可帮助您改进 Core Web Vitals 指标。如果您刚开始接触网站性能,或者仍在确定哪些措施可以带来最高的投资回报率,不妨从这篇文章入手。

Interaction to Next Paint (INP)

作为最新的 Core Web Vitals 指标,Interaction to Next Paint (INP) 有许多值得改进的地方。不过,与已废弃的前身相比,能够达到“良好”体验阈值的网站数量要少得多,因此您可能也是首次学习如何优化互动响应能力的众多开发者之一。不妨先了解这些必备技巧,以便以最有效的方式提升 INP。

1. 经常使用 yield 来拆分长任务

任务是指浏览器执行的任何单独工作,包括呈现、布局、解析、编译或执行脚本。当任务时长超过 50 毫秒时,就会成为长任务。冗长任务会造成问题,因为它们可能会阻止主线程快速响应用户互动。

虽然您应始终努力在 JavaScript 中尽可能少做工作,但您可以通过拆分长任务来帮助主线程。为此,您可以经常让出主线程,以便更快地进行渲染更新和其他用户互动。

Browser Support

  • Chrome: 129.
  • Edge: 129.
  • Firefox: not supported.
  • Safari: not supported.

Source

借助 Scheduler API,您可以使用优先级系统将工作加入队列。具体而言,scheduler.yield() API 会拆分长任务,同时确保能够在不放弃任务队列中的位置的情况下处理互动。

通过拆分长任务,您可以让浏览器有更多机会执行会阻塞用户的关键工作。

2. 避免使用不必要的 JavaScript

网站所提供的 JavaScript 比以往任何时候都多,而且这种趋势似乎不会改变。如果您提交的 JavaScript 过多,就会造成任务争夺主线程的注意力。这可能会影响网站的响应速度,尤其是在关键的启动期间。

不过,这并不是一个无法解决的问题,您可以采取以下措施:

  • 使用基准广泛提供的 Web 平台功能,而不是冗余的基于 JavaScript 的实现。
  • 使用 Chrome DevTools 中的覆盖率工具查找脚本中的未使用代码。通过缩减启动期间所需资源的大小,您可以确保网页花在解析和编译代码上的时间更少,从而提供更流畅的初始用户体验。
  • 使用代码分块为初始渲染不需要但日后仍会使用的代码创建单独的软件包。
  • 如果您使用的是跟踪代码管理器,请定期优化代码。您可以移除包含未使用的代码的旧版代码,以缩减跟踪代码管理器的 JavaScript 占用空间。

3. 避免进行大规模渲染更新

JavaScript 执行只是影响网站响应速度的众多因素之一。渲染本身就是一项耗费资源的工作,在进行大型渲染更新期间,您的网站对用户互动做出响应的速度可能会更慢。

优化渲染工作并非一个简单的过程,具体取决于您要实现的目标。即便如此,您也可以采取以下措施来确保渲染任务不会变成长任务:

  • 重新整理 JavaScript 代码中的 DOM 读写操作,以避免强制布局布局抖动
  • 使 DOM 大小保持小巧。DOM 大小与布局工作强度相关。当渲染程序必须更新非常大的 DOM 的布局时,重新计算其布局所需的工作量可能会大幅增加。
  • 使用 CSS 容器来延迟渲染屏幕外 DOM 内容。这并不总是简单明了,但通过隔离包含复杂布局的区域,您可以避免不必要的布局和渲染工作。

Largest Contentful Paint (LCP)

Largest Contentful Paint (LCP) 是开发者最难把控的 Core Web Vitals 指标:Chrome 用户体验报告中40%的网站未达到建议的 LCP 阈值,无法提供良好的用户体验。Chrome 团队建议采用以下技术来最有效地缩短 LCP。

1. 确保 LCP 资源可从 HTML 源中发现并获得优先级

Chrome 团队注意到,在 Web 上,LCP 存在以下问题:

  • 根据 HTTP Archive 的 2024 年网络年鉴73% 的移动网页将图像作为 LCP 元素。
  • 对 Chrome 中的真实用户数据进行分析后发现,大多数 LCP 较差的来源在 75 百分位数 LCP 时间的不到 10%用于下载 LCP 图片。
  • 在 LCP 较差的网页中,75 百分位数的 LCP 图片在客户端上的加载延迟时间为 1,290 毫秒,这超过了快速体验预算的一半。
  • 在 LCP 元素为图片的网页中,35% 的图片的来源网址在初始 HTML 响应中不可检测(例如 <img src="..."><link rel="preload" href="...">),这会导致浏览器的预加载扫描器无法尽快发现这些图片。
  • 根据《网络年鉴》的统计,15% 符合条件的网页利用 fetchpriority HTML 属性为资源分配更高的优先级,包括那些可以相对轻松地提升网页 LCP 的资源。

这些统计数据表明,开发者有很大的机会缩短 LCP 图片的资源加载延迟时间资源加载时长

Browser Support

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 132.
  • Safari: 17.2.

Source

如果资源加载延迟是问题所在,请务必注意,如果网页需要等待 CSS 或 JavaScript 完全加载后才能开始加载图片,那么可能已经太晚,无法实现良好的 LCP。此外,您还可以使用 fetchpriority HTML 属性重新调整 LCP 图片的优先级,以便其获得更多带宽,从而加快加载速度,从而缩短资源加载时长。

如果您的 LCP 元素是图片,则应在 HTML 响应中发现图片的网址,以缩短其资源加载延迟时间。以下是一些有助于实现这一目标的提示:

  • 使用带有 srcsrcset 属性的 <img> 元素加载图片。请勿使用需要 JavaScript 才能呈现的非标准属性(例如 data-src),因为这类属性的速度始终较慢。7% 的网页会将其 LCP 图片隐藏在 data-src 后面。
  • 优先使用服务器端呈现 (SSR),而不是客户端呈现 (CSR),因为 SSR 意味着 HTML 源代码中包含完整的网页标记(包括图片)。CSR 解决方案需要先运行 JavaScript,然后才能发现图片。
  • 如果需要从外部 CSS 或 JS 文件引用图片,您仍然可以使用 <link rel="preload"> 标记将其添加到 HTML 源中。请注意,内嵌样式引用的图片无法被浏览器的预加载扫描器发现,因此即使在 HTML 源代码中找到这些图片,在加载其他资源时,系统可能仍会阻止发现它们,因此在这种情况下,预加载会很有帮助。

此外,您还可以确保 LCP 资源尽早加载并采用高优先级,从而缩短资源的加载时长:

  • fetchpriority="high" 属性添加到 LCP 图片的 <img><link rel="preload"> 标记。这会提高图片资源的优先级,以便其更早开始加载。
  • 从 LCP 图片的 <img> 标记中移除 loading="lazy" 属性。这样可以避免因确认图片是否显示在视口中或附近而导致的加载延迟。
  • 尽可能推迟非关键资源的加载。将这些资源移至文档末尾、延迟加载图片iframe,或者使用 JavaScript 异步加载这些资源,有助于为 LCP 图片等更重要的资源腾出空间,以便它们更快加载。

2. 力求实现即时导航

理想的用户体验是,用户无需等待网页加载。资源可检测性和优先级等 LCP 优化措施可以有效缩短用户等待 LCP 元素加载和呈现的时间,但这些字节通过网络加载并在网页上呈现的速度存在物理限制。在达到该上限之前,您需要付出极大的努力才能再缩短几毫秒。因此,为了实现即时导航,我们需要采用完全不同的方法。

即时导航会尝试在用户开始导航到相应网页之前加载和呈现该网页。这样一来,预渲染的网页便可立即显示,并且 LCP 几乎为零。恢复和推测是实现此目的的两种方法。当用户返回或前进到之前访问过的网页时,系统可以从内存缓存中快速恢复该网页,使其显示的样子与用户离开时完全一样。或者,Web 应用也可以尝试预测用户接下来会去哪里,如果预测正确,那么当用户导航到该网页时,下一个网页就会已加载并呈现。

往返缓存 (bfcache) 可用于恢复之前访问过的网页。如需使用此功能,您必须确保您的网页符合 bfcache 资格条件。网页不符合 bfcache 条件的常见原因是,它们使用 no-store 缓存指令进行传送或具有 unload 事件监听器。

恢复完全呈现的网页不仅可以提升加载性能,还可以提高布局稳定性。如需详细了解 bfcache 以及它在提高 CLS 方面的有效性,请参阅确保网页符合 bfcache 使用条件部分。

Browser Support

  • Chrome: 109.
  • Edge: 109.
  • Firefox: not supported.
  • Safari: not supported.

预渲染用户下次访问的网页是显著提升 LCP 性能的另一种有效方法,可通过 Speculation Rules API 实现。不过,要想实现这些优势,请确保预渲染正确的网页。错误的推测会浪费服务器和客户端上的资源,从而影响性能。因此,您对下一页内容的把握越不确定,就越应谨慎地预渲染该页面。当您有疑问时,可以参考分析数据,更放心地更积极地预渲染最有可能被下次访问的网页。

3. 使用 CDN 优化 TTFB

之前的建议侧重于即时导航,可为用户提供尽可能出色的体验,但在某些情况下,bfcache 和推测性加载技术可能不适用。假设用户通过跨源链接访问您的网站,其中初始 HTML 文档响应会有效阻止 LCP。在收到响应的第一个字节之前,浏览器无法开始加载任何子资源。越早完成,其他所有工作就能越早开始。

这段时间称为至第一字节的时间 (TTFB)。缩短 TTFB 的最佳方法是:

  • 尽可能在距离用户地理位置最近的位置传送内容。
  • 缓存该内容,以便在近期再次收到请求时快速提供该内容。

要同时实现这两点,最佳方式是使用 CDN。CDN 会将您的资源分发到全球各地的边缘服务器,从而缩短这些资源通过线路传输到用户的距离。CDN 通常还具有精细的缓存控制功能,可根据您网站的需求进行调整。

CDN 还可以提供和缓存 HTML 文档,但根据《网络年鉴》的统计,只有 33% 的 HTML 文档请求由 CDN 提供。这意味着,网站有很大机会进一步节省开支。

关于配置 CDN 的一些提示包括:

  • 缓存静态 HTML 文档,即使只是短时间。例如,内容是否始终保持新鲜度很重要吗?或者可以延迟几分钟吗?
  • 探索是否可以将在源服务器上运行的动态逻辑移至边缘(这是大多数新型 CDN 的一项功能)。

只要您能直接从边缘服务器提供内容,并避免访问源服务器,就能提升性能。即使您必须一直访问到源站,CDN 通常也会经过优化,以便更快地完成访问,因此无论哪种方式,您都能获益。

Cumulative Layout Shift (CLS)

Cumulative Layout Shift (CLS) 用于衡量网页的视觉稳定性。虽然 CLS 是大多数网站的优势指标,但仍有四分之一的网站未达到建议的阈值,因此许多网站仍有很大的机会改进用户体验。

1. 为从网页加载的任何内容设置明确的尺寸

布局偏移通常发生在其他内容加载完毕后现有内容移动时。提高 CLS 的主要方法是尽可能提前预留所需空间。

若要解决由未调整大小的图片导致的布局偏移问题,最好的方法是明确设置 widthheight 属性或其等效的 CSS 属性。66% 的网页至少包含一张未调整大小的图片。如果没有明确的尺寸,这些图片的初始高度为 0px,这可能会导致在这些图片加载并浏览器发现其尺寸时,布局发生偏移。这对集体网络来说是一个巨大的机遇,而且相较于本指南中建议的其他一些做法,抓住这个机遇所需的工作量更少。

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 89.
  • Safari: 15.

Source

图片并非 CLS 的唯一贡献者。布局偏移可能是由通常在网页初次呈现后加载的其他内容(包括第三方广告或嵌入的视频)导致的。aspect-ratio 属性可以派上用场。这是一种广泛使用的基准 CSS 功能,可让开发者为图片和非图片元素显式设置宽高比。这样,您就可以设置动态 width(例如基于屏幕尺寸),并让浏览器自动计算适当的高度,就像为具有尺寸的图片计算高度一样。

不过,我们并不总能知道动态内容的确切大小。即使您不知道确切大小,也仍然可以降低布局偏移的严重程度。设置合理的 min-height 通常比允许浏览器为空元素使用默认高度 0px 更好。使用 min-height 通常也是一个简单的解决方法,因为它仍然允许容器在需要时增长到最终内容的高度,只是将增长量减少到更可接受的水平。

2. 确保网页符合 bfcache 的使用条件

如本指南前面所述,往返缓存 (bfcache) 会从内存快照中即时加载浏览器历史记录中较早或较晚的网页。虽然 bfcache 是一项重要的浏览器级性能优化,可提升 LCP,但它还能完全消除布局偏移。事实上,2022 年引入 bfcache 是当年 CLS 改善幅度最大的因素。

尽管如此,大量网站不符合使用 bfcache 的条件,因此错失了这一免费的网站性能提升机会。除非您的网页正在加载您不希望从内存恢复的敏感信息,否则请确保您的网页符合使用 bfcache 的条件。

网站所有者应检查网页是否符合 bfcache 使用条件,并修正导致网页不符合条件的所有原因。Chrome 在开发者工具中提供了 bfcache 测试工具,您还可以使用 Not Restored Reasons API 来检测该字段中的不符合条件的原因。

3. 避免使用会导致布局的 CSS 属性的动画和过渡

布局偏移的另一个常见原因是元素呈现动画效果。例如,从顶部或底部滑入的 Cookie 横幅或其他通知横幅通常会导致 CLS 增加。如果这些横幅会将其他内容推开,这种情况尤其严重,但即使不会,为其添加动画效果也可能会影响 CLS。

虽然 HTTP 归档数据无法确切地将动画与布局偏移联系起来,但数据确实表明,与整体网页相比,如果网页为可能会影响布局的任何 CSS 属性添加动画,CLS 达到“良好”水平的可能性会降低 15%。某些媒体资源的 CLS 比其他媒体资源要高。例如,在整体页面被评为 CLS 较差的网页中,采用 marginborder 宽度动画的网页被评为 CLS 较差的网页占比几乎是前者的两倍。

这可能并不令人意外,因为每当您对任何可导致布局的 CSS 属性进行转换或添加动画时,都会导致布局偏移。如果这些布局偏移不在用户互动后的 500 毫秒内发生,则会影响 CLS。

有些开发者可能会感到意外,即便元素不在正常文档流中,也是如此。例如,对 topleft 进行动画处理的绝对定位元素会导致布局偏移,即使它们没有推送其他内容也是如此。不过,如果您对 transform:translateX()transform:translateY() 进行动画处理,而不是对 topleft 进行动画处理,则不会导致浏览器更新网页布局,从而避免布局偏移。

长期以来,优先使用可在浏览器的合成器线程上更新的 CSS 属性进行动画处理一直是性能方面的最佳实践,因为这会将工作从主线程移至 GPU。除了是一项常见的效果最佳实践之外,它还有助于提升 CLS。

一般来说,请勿为需要浏览器更新页面布局的 CSS 属性添加动画或转换,除非您是在响应用户点按或按键操作(但不是 hover)时执行此操作。请尽可能使用 CSS transform 属性实现转换和动画。

当页面为可能运行缓慢的 CSS 属性添加动画时,避免使用未合成的动画 Lighthouse 审核会发出警告。

总结

提升网页性能可能看起来很难,尤其是考虑到网络上有大量的指导信息需要参考。不过,通过重点关注这份最有效的最佳实践简短列表,您可以重新专注于解决问题,并有望提升网站的核心 Web 指标。

如果您想采取上述优化措施之外的措施,请参阅以下指南了解详情:

附录:更新日志

我们会在此处跟踪本文档的重大更改,以便说明热门建议何时发生变化以及原因。

2024 年 10 月

2024 年更新:

  • INP
    • 随着 INP 作为 Core Web Vitals 指标发布,我们将此指标从 FID 改为了 INP,并将其列为列表中的首个指标。
    • 我们撤消了建议在拆分长任务时使用 isInputPending API 的建议。如需详细了解我们的推理过程,请参阅优化长时间运行的任务一文。
  • LCP
    • 我们将可检测性和优先级建议合并为一个建议。
    • 我们添加了旨在实现即时导航的新建议。

2023 年 1 月

以下是初始建议列表:

  • LCP
    • 确保 LCP 资源可从 HTML 源代码中发现
    • 确保 LCP 资源的优先级较高
    • 使用 CDN 优化文档和资源的 TTFB
  • CLS
    • 为从网页加载的任何内容设置明确的尺寸
    • 确保网页符合 bfcache 的使用条件
    • 避免使用会导致布局的 CSS 属性的动画和过渡
  • FID
    • 避免或拆分长任务
    • 避免使用不必要的 JavaScript
    • 避免进行大规模渲染更新

您还可以观看这场 2023 年 Google I/O 大会演讲,了解视频摘要。