Chrome DevRel 团队认为在 2023 年提升 Core Web Vitals 性能的最有效方法的一系列最佳实践。
多年来,Google 向 Web 开发者提供了许多关于如何提升性能的建议。
虽然这些建议单独都会对许多网站的效果有所提升,但无疑是一整套建议让人应接不暇,事实上,任何个人或网站都不可能采纳所有这些建议。
除非您的日常工作不是提高网页性能,否则哪些建议会对您的网站产生最大的积极影响,这些可能并不明显。例如,您可能已经了解到实施关键 CSS 可以提高加载性能,可能也听说到优化图片非常重要。但是,如果你没有时间处理这两件事,你会如何决定选择哪一个呢?
Chrome 团队在过去一年中一直在尝试回答这样一个问题:我们可以为开发者提供哪些最重要的建议来帮助他们为用户提升性能?
为了充分回答这个问题,我们不仅要考虑任何给定建议的技术优势,还要考虑可影响开发者实际采用这些建议可能性的人为因素和组织因素。换言之,有些建议在理论上可能具有巨大影响,但实际上,很少有网站有时间或资源来实施这些建议。同样,有些建议至关重要,但大多数网站都已遵循这些做法。
简而言之,我们希望一系列热门网站性能建议侧重于以下方面:
- 我们认为在实际工作中产生的影响最大的建议
- 相关推荐内容与大多数网站相关且适用于大多数网站
- 建议对大多数开发者而言切实可行
在过去的一年里,我们花了大量时间来审核我们提出的全部效果建议,并根据上述三个标准(从定性和定量角度)对每条建议进行评估。
此博文概述了我们针对各个核心网页指标指标提供的重要建议。如果您刚开始接触网络性能,或者想要确定什么能为您带来最大收益,那么这些建议就是最佳选择。
Largest Contentful Paint (LCP)
我们的第一组建议针对的是 Largest Contentful Paint (LCP),LCP 是一种衡量加载性能的方法。在 Core Web Vitals 的三个指标中,LCP 是影响最大的网站数量最多的指标(目前网络上只有约一半的网站达到了建议的阈值),所以我们先来介绍一下。
确保 LCP 资源可通过 HTML 源代码检测到
根据 HTTP Archive 的 2022 年网络年鉴,72% 的移动网页使用图片作为 LCP 元素,这意味着,对于大多数要优化 LCP 的网站来说,他们需要确保能够快速加载这些图片。
对许多开发者来说,可能并不明显的一点是,加载图像所需的时间只是挑战的一部分。另一个关键部分是图片开始加载之前的时间,而 HTTP Archive 数据表明,这实际上是许多网站开始加载之前的时间。
事实上,在 LCP 元素为图片的网页上,有 39% 的图片的来源网址无法在 HTML 文档来源中发现。也就是说,这些网址无法在标准 HTML 属性(例如 <img src="...">
或 <link rel="preload" href="...">
)中找到,而这会导致浏览器快速发现它们并立即开始加载它们。
如果网页需要等待 CSS 或 JavaScript 文件完成下载、解析和处理,然后图片才能开始加载,这可能已经为时已晚。
一般来说,如果您的 LCP 元素是图片,应始终可通过 HTML 源代码找到该图片的网址。下面这些技巧可以帮助您实现这一目标:
使用具有
src
或srcset
属性的<img>
元素加载图片。请勿使用需要 JavaScript 才能呈现的非标准属性(如data-src
),因为此类属性总是会变慢。9% 的网页遮挡了data-src
后面的 LCP 图片。首选服务器端呈现 (SSR) 而非客户端呈现 (CSR),因为 SSR 意味着 HTML 源代码中存在整页标记(包括图片)。CSR 解决方案要求在发现映像之前运行 JavaScript。
如果您需要从外部 CSS 或 JS 文件中引用您的图片,您仍然可以通过
<link rel="preload">
标记将其包含在 HTML 源代码中。请注意,浏览器的预加载扫描器无法发现内嵌样式引用的图片,因此即使 HTML 源代码中能找到这些图片,在加载其他资源时,系统仍可能会阻止发现这些图片,因此在这些情况下预加载可能会有所帮助。
为了帮助您了解 LCP 映像是否存在可检测性问题,Lighthouse 将在 10.0 版(预计 2023 年 1 月)中发布一项新的审核。
确保 LCP 资源可从 HTML 源代码中发现可以带来可衡量的改进,并且还可以解锁更多机会来确定资源的优先级,这就是我们的下一项建议。
确保优先使用 LCP 资源
确保可以从 HTML 源代码中发现 LCP 资源,这是确保 LCP 资源可提早开始加载的关键第一步,但另一个重要步骤是确保该资源的优先加载,而不会排在大量其他不太重要的资源后面。
例如,即使您的 LCP 图片显示在 HTML 源代码中使用标准 <img>
标记的情况下,如果您的网页在文档的 <head>
中的 <img>
标记前面添加了十几个 <script>
标记,图片资源可能要过一段时间才会开始加载。
解决此问题的最简单方法是,在加载 LCP 图片的 <img>
或 <link>
标记上设置新的 fetchpriority="high"
属性,从而提示浏览器哪些资源的优先级最高。这将指示浏览器提前加载,而不是等待这些脚本完成。
根据《Web Almanac》的资料,只有 0.03% 的符合条件的网页在利用了这一新 API,这意味着网络上的大多数网站都有很大的机会来改进 LCP,而且只需极少的工作量。虽然 fetchpriority
属性目前仅在基于 Chromium 的浏览器中受支持,但此 API 是一项渐进增强功能,已被其他浏览器忽略,因此我们强烈建议开发者立即使用。
对于非 Chromium 浏览器,确保 LCP 资源优先级高于其他资源的唯一方法是在文档的前面部分引用该资源。再次以该网站的 <head>
中含有大量 <script>
标记的网站为例,如果您想确保 LCP 资源优先于这些脚本资源,可以在其中任何脚本之前添加 <link rel="preload">
标记,也可以稍后在 <body>
中将这些脚本移至 <img>
下方。虽然这样行得通,但与使用 fetchpriority
相比,它不符合人体工程学,因此我们希望其他浏览器能尽快添加支持。
确定 LCP 资源优先级的另一个关键方面是,确保不执行任何会导致其降低优先级的操作,例如添加 loading="lazy"
属性。如今,10% 的网页实际上为其 LCP 图片设置了 loading="lazy"
。请注意会对所有图片随意应用延迟加载行为的图片优化解决方案。如果它们提供覆盖该行为的方法,请务必将其用于 LCP 图片。如果您不确定哪张图片将是 LCP,请尝试使用启发法选择合理的候选图片。
推迟非关键资源是有效提高 LCP 资源的相对优先级的另一种方法。例如,无法为界面提供支持的脚本(如分析脚本或社交微件)可以安全地推迟到 load
事件触发之后,以确保它们不会与其他关键资源(如 LCP 资源)争用网络带宽。
总而言之,您应遵循以下最佳实践,以确保尽早以高优先级加载 LCP 资源:
- 将
fetchpriority="high"
添加到 LCP 映像的<img>
标记中。如果 LCP 资源是通过<link rel="preload">
标记加载的,请不要担心,因为您也可以对其设置fetchpriority="high"
! - 切勿在 LCP 映像的
<img>
标记上设置loading="lazy"
。这样做会降低图片的优先级,并延迟图片开始加载的时间。 - 尽可能推迟非关键资源。方法是将它们移到文档末尾、为图片或 iframe 使用原生延迟加载,或者通过 JavaScript 异步加载它们。
使用 CDN 优化文档和资源 TTFB
前两项建议侧重于确保及早发现 LCP 资源并对其进行优先处理,以便能够立即开始加载。最后一点,就是要确保最初的文档响应也能尽快到达。
浏览器在收到初始 HTML 文档响应的第一个字节之前,无法开始加载任何子资源,而且越早加载,其他一切也会开始发生。
这个时间称为第一字节时间 (TTFB),减少 TTFB 的最佳方法是:
- 在地理位置上尽可能靠近用户的位置发布内容
- 缓存该内容,以便快速再次提供最近请求的内容。
为实现这两个目标,最佳方法是使用 CDN。CDN 会将您的资源分发到分布在全球各地的边缘服务器,从而限制这些资源通过网络传输到用户处的距离。CDN 通常还具有精细的缓存控件,您可以根据网站的需求对其进行自定义和优化。
许多开发者都熟悉如何使用 CDN 来托管静态资源,但 CDN 也可以提供和缓存 HTML 文档,甚至是动态生成的文档。
根据《Web Almanac》的资料,只有 29% 的 HTML 文档请求是通过 CDN 处理的,这意味着网站极有可能申请更多优惠。
以下是关于配置 CDN 的一些提示:
- 考虑增加内容的缓存时长(例如,内容始终是最新的是否真的很重要?也可能是几分钟就过时了?)
- 可以考虑无限期地缓存内容,然后在更新时完全清除缓存。
- 探索是否可以将源服务器中当前运行的动态逻辑移至边缘(大多数现代 CDN 的一项功能)。
一般来说,每当您可以直接从边缘传送内容(避免前往您的源服务器)时,性能都会得到提升。即使您确实不得不从始至终返回到源服务器,CDN 通常经过优化,可以更快地实现这一点,因此这两种方式都是双赢的。
Cumulative Layout Shift (CLS)
下一组建议针对的是 Cumulative Layout Shift (CLS),CLS 用于衡量网页上的视觉稳定性。虽然自 2020 年以来,虽然 CLS 在网络上取得了很大的改进,但大约四分之一的网站仍未达到建议的阈值,因此许多网站仍有很大机会改善用户体验。
为从网页加载的任何内容设置明确的尺寸
当现有内容在其他内容加载完毕后移动时,通常会发生布局偏移。因此,缓解此问题的主要方法是尽可能提前预留任何所需的空间。
要解决因图片大小不合适而导致的布局偏移,最直接的方法是明确设置 width
和 height
属性(或等效的 CSS 属性)。但根据 HTTP Archive 数据,72% 的网页至少有一张未调整大小的图片。如果没有明确的尺寸,浏览器最初会将默认高度设置为 0px
,并且在最终加载图片并发现尺寸时,可能会导致布局发生明显的偏移。这对整个网络来说都是一个巨大的机遇,而且与本文中建议的其他一些建议相比,这个机遇所需的工作量要小得多。
还要注意的是,图片并不是 CLS 的唯一促成因素。通常在网页首次呈现后加载的其他内容(包括第三方广告或嵌入式视频)可能会导致布局偏移。aspect-ratio
属性有助于解决此问题。这是一项相对较新的 CSS 功能,允许开发者为图片和非图片元素明确提供宽高比。这样,您就可以设置动态 width
(例如,根据屏幕尺寸),并让浏览器自动计算合适的高度,计算方法与计算包含尺寸的图片大致相同。
有时,由于动态内容本身就是动态的,因此无法知道其确切大小。不过,即使您不知道确切大小,仍然可以采取措施来降低布局偏移的严重程度。与允许浏览器对空元素使用默认高度 0px
相比,设置合理的 min-height
几乎总是优于设置。通常,使用 min-height
也是一种简单的修复方法,因为它仍允许容器根据需要增长到最终内容高度,它只是将增长量从全部量减到了希望更容易容忍的水平。
确保网页符合使用 bfcache 的条件
浏览器使用一种称为往返缓存(简称 bfcache)的导航机制,直接从内存快照中即时加载浏览器历史记录中较早或较晚的网页。
bfcache 是一项重要的浏览器级性能优化,它完全消除了网页加载期间的布局偏移,对于许多网站来说,其 CLS 大多发生于网页加载期间。bfcache 的引入带来了 CLS 的最大改进,这是我们在 2022 年看到的。
尽管如此,大量网站都不符合使用 bfcache 的条件,这导致大量的导航无法享受这项免费的网页性能优势。除非您的网页正在加载您不想从内存中恢复的敏感信息,否则您需要确保网页符合条件。
网站所有者应检查自己的网页是否符合加入 bfcache 的条件,并设法找出导致其不符合资格的所有原因。Chrome 已在开发者工具中集成了 bfcache 测试人员,今年,我们计划通过执行类似测试的新 Lighthouse 审核和用于现场衡量这一点的 API 来增强这里的工具。
虽然我们在 CLS 部分中添加了 bfcache,虽然迄今为止我们获得了最大收益,但 bfcache 通常也会改进其他核心网页指标。它是众多即时导航方式之一,可显著改善网页导航体验。
避免使用会引发布局的 CSS 属性的动画/过渡
布局偏移的另一个常见原因是元素为动画。例如,从顶部或底部滑入的 Cookie 横幅或其他通知横幅通常是增加 CLS 的因素。当这些横幅广告将其他内容移开时,这一问题尤为突出,但即使这样,为这些内容设置动画仍可能会影响 CLS。
虽然 HTTP Archive 数据无法最终将动画与布局偏移关联起来,但数据确实显示,为任何可能影响布局的 CSS 属性添加动画效果的页面具有“良好”的可能性要低 15%CLS。某些房源的 CLS 低于其他房源。例如,为 margin
或 border
宽度添加动画效果的网页CLS 几乎是网页整体评估结果差的两倍。
这可能并不奇怪,因为每当您为任何布局诱导的 CSS 属性转换或添加动画效果时,都会导致布局偏移,而如果这些布局偏移不在用户互动的 500 毫秒内,就会影响 CLS。
有些开发者可能出乎意料的是,即使元素是在正常的文档流程以外获取的,也是如此。例如,为 top
或 left
添加动画效果的绝对定位元素会导致布局偏移,即使它们不会四处推动其他内容也是如此。不过,如果您不是为 top
或 left
添加动画效果,而是为 transform:translateX()
或 transform:translateY()
添加动画效果,不会导致浏览器更新页面布局,因此也不会产生任何布局偏移。
首选可以在浏览器的合成器线程上更新的 CSS 属性动画长期以来一直是性能最佳实践,因为它将工作移到 GPU 上,而不是主线程外。除了是一种常规性能最佳实践,它还有助于改进 CLS。
一般来说,切勿为任何需要浏览器更新页面布局的 CSS 属性添加动画效果或进行转换,除非您是为响应用户点按或按键操作(但不是 hover
)。请尽可能优先使用 CSS transform
属性的过渡和动画效果。
当页面为可能较慢的 CSS 属性添加动画效果时,Lighthouse 的避免使用非合成动画功能会发出警告。
First Input Delay (FID)
我们的最后一组建议针对的是 First Input Delay (FID),FID 用于衡量网页对用户互动的响应情况。虽然目前大多数网站在 FID 方面的得分都非常高,但我们过去记录了 FID 指标的不足之处,我们认为网站仍有很大的机会来提高对用户互动的总体响应能力。
我们新的 Interaction to Next Paint (INP) 指标可能会取代 FID,以下所有建议同样适用于 FID 和 INP。鉴于网站在 INP 上的效果不如 FID,尤其是在移动设备上,我们建议开发者认真考虑这些响应速度建议,尽管其表现“良好”FID。
避免或拆分耗时较长的任务
任务是浏览器执行的任何离散工作。任务包括渲染、布局、解析以及编译和执行脚本。当任务变成耗时较长的任务(即 50 毫秒或更长时间)时,它们会阻止主线程快速响应用户输入。
根据《网络年鉴》,有充足的证据表明,开发者可以采取更多措施来避免或拆分耗时较长的任务。虽然拆分耗时较长的任务可能不像本文中的其他建议那样容易,但与本文中未介绍的其他方法相比,难度要小。
虽然您应始终努力尽量减少在 JavaScript 中完成的工作,但您可以通过将较长的任务分解成若干较小的任务,为主线程带来极大的帮助。为此,您可以经常让出到主线程,以便更快地进行渲染更新和其他用户互动。
另一种方法是考虑使用 isInputPending
和 Scheduler API 等 API。isInputPending
是一个函数,可返回一个布尔值,指示用户输入是否处于待处理状态。如果它返回 true
,您可以让给主线程,以便它处理待处理的用户输入。
Scheduler API 是一种更高级的方法,允许您根据优先级系统安排工作,而优先级系统会考虑正在进行的工作是用户可见还是在后台运行。
分解冗长的任务,为浏览器提供更多机会来适应关键的用户可见工作,例如处理互动和由此产生的任何渲染更新。
避免使用不必要的 JavaScript
毫无疑问:网站支持的 JavaScript 数量比以往任何时候都多,而且这一趋势在短期内不会有任何变化。当您发送过多 JavaScript 时,会创建一个环境,其中任务会争夺主线程的注意力。这无疑会影响您网站的响应能力,尤其是在关键的启动期间。
不过,这不是一个无法解决的问题。您确实有以下几种选择:
- 使用 Chrome 开发者工具中的覆盖率工具查找网站资源中未使用的代码。通过缩减启动期间所需资源的大小,您可以确保网站节省在解析和编译代码上花费的时间,从而提供更顺畅的初始用户体验。
- 有时,使用覆盖率工具发现的未使用的代码会被标记为“未使用”因为它未在启动期间执行,但对于将来的某些功能而言仍然是必需的。您可以通过代码拆分将这些代码移至单独的 bundle 中。
- 如果您使用的是跟踪代码管理器,请务必定期检查代码,确保代码已得到优化,即使代码仍在使用中也应如此。您可以清除包含未使用的代码的旧代码,从而缩减跟踪代码管理器的 JavaScript 大小,提高效率。
避免大规模渲染更新
JavaScript 并不是唯一会影响网站响应能力的因素。渲染本身就是一种成本高昂的工作,当发生大量渲染更新时,它们可能会干扰您的网站响应用户输入的能力。
优化渲染工作不是一个简单直接的过程,通常要取决于您想要实现的目标。即便如此,您还是可以采取一些措施,确保渲染更新合理,避免耗时长的任务处理:
- 避免使用
requestAnimationFrame()
执行任何非视觉工作。requestAnimationFrame()
调用在事件循环的渲染阶段进行处理,如果在此步骤中执行太多工作,渲染更新可能会延迟。使用requestAnimationFrame()
执行的任何工作都应严格专用于涉及渲染更新的任务。 - 保持较小的 DOM 大小。DOM 大小与布局工作的强度是相关的。当渲染程序必须为超大型 DOM 更新布局时,重新计算其布局的工作量可能会大幅增加。
- 使用 CSS 控件。CSS 包含依赖于 CSS
contain
属性,该属性会向浏览器说明如何为设置了contain
属性的容器执行布局工作,包括甚至将布局范围和渲染隔离到 DOM 中的特定根。这并不总是简单的过程,但是通过隔离包含复杂布局的区域,可以避免对它们进行不必要的布局和渲染工作。
总结
提升网页性能似乎是一项艰巨的任务,尤其是考虑到网络上有大量指南需要考虑。不过,通过关注这些建议,您可以有的放矢地解决问题,并有望为您网站的核心网页指标更进一步。
虽然此处列出的建议并非详尽无遗,但根据对网络状况的仔细分析,我们相信,这些建议是网站在 2023 年提升其核心网页指标性能的最有效方式。
如果您不想仅仅局限于本文中所列的建议,不妨参阅以下优化指南以了解详情:
新的一年,让大家畅享更快的上网体验!希望您的网站能以所有最重要的方面为您的用户快速加载。
摄影:Devin Avery