Chrome DevRel 团队认为的一系列最佳实践是在 2023 年提高核心网页指标性能的最有效方式。
这些年,Google 就如何提高性能向 Web 开发者提供了很多建议。
虽然这些建议各自能够提升许多网站的效果,但一整套建议无疑极具说服力,实际上,任何个人或网站都不可能采纳所有这些建议。
除非您日常工作需要提高网站性能,否则很难轻松判断哪些建议会对您的网站产生最大的积极影响。例如,您可能已经了解到,实现关键的 CSS 可以提高加载性能,并且您可能也听说过优化图片非常重要。但是,如果您没有时间同时兼顾这两点,您会如何决定选择哪一种呢?
Chrome 团队去年一直在尝试回答以下问题:为帮助开发者提升用户性能,我们可以给开发者提供哪些最重要的建议?
为了充分回答这个问题,我们不仅要考虑任何给定建议的技术价值,还要考虑人为和组织因素,这些因素会影响开发者实际采用这些建议的可能性。换句话说,有些建议在理论上可能效果非常好,但实际上很少有网站有时间或资源来实施这些建议。同样,一些建议至关重要,但大多数网站已经在遵循这些做法。
简而言之,我们希望我们的热门网页性能建议列表侧重于:
- 我们认为将对现实世界产生最大影响的建议
- 与大多数网站相关且适用于大多数网站的建议
- 对大多数开发者来说切实可行的建议
在过去的一年里,我们花费了大量时间对我们提出的全部效果提升建议进行审核,并根据上述三个标准对每条建议进行定性和定量评估。
这篇博文概述了一些有助于提升各个核心网页指标指标的重要建议。如果您刚开始接触 Web 性能,或者想要决定什么能为您带来最大收益,那么我们认为这些建议是最佳起点。
Largest Contentful Paint (LCP)
我们的第一组建议是 Largest Contentful Paint (LCP),该值用于衡量加载性能。在三个 Core Web Vitals 指标中,LCP 是受影响最多的网站数量,目前只有大约一半的网站达到建议的阈值,让我们从这个阈值开始吧。
确保可从 HTML 源代码中找到 LCP 资源
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 月发布)。
确保可以找到 HTML 源代码中的 LCP 资源可以带来可衡量的改进,还可以创造更多机会来优先列出相应资源,这是我们的下一条建议。
确保优先考虑 LCP 资源
确保可从 HTML 源代码中发现 LCP 资源是确保 LCP 资源尽早开始加载的关键第一步,但另一个重要步骤是确保对该资源的加载优先,不会排队等待其他不太重要的资源排队。
例如,即使您的 LCP 图片显示在使用标准 <img>
标记的 HTML 源代码中,但如果网页在文档的 <head>
中的 <img>
标记之前有十几个 <script>
标记,也可能需要过一段时间才会开始加载图片资源。
解决此问题的最简单方法是,在用于加载 LCP 图片的 <img>
或 <link>
标记上设置新的 fetchpriority="high"
属性,告知浏览器哪些资源的优先级最高。这会指示浏览器提前加载,而不是等待这些脚本完成。
根据《网络年报》的数据,只有 0.03% 符合条件的网页采用了这一新 API,这意味着网站上的大多数网站有很大的改进 LCP 的机会,而且只需完成很少的工作。虽然目前只有基于 Chromium 的浏览器支持 fetchpriority
属性,但此 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 文档,即使是动态生成的文档也是如此。
根据《网络年鉴》的数据,只有 29% 的 HTML 文档请求来自 CDN,这意味着网站有很大机会声称可以节省更多费用。
以下是配置 CDN 的一些提示:
- 考虑增加内容的缓存时长(例如,是否必须确保内容始终保持最新状态?还是有可能只是过时几分钟?)。
- 您甚至可以考虑无限期地缓存内容,然后在进行更新时清除缓存。
- 探索是否可以将源服务器上当前运行的动态逻辑移至边缘(大多数新型 CDN 的一项功能)。
一般来说,只要您能直接从边缘传送内容(无需前往源服务器),就能提升性能。即使您确实不得不返回源服务器,CDN 一般也会经过优化,可以更快地完成该操作,因此这两种方式都能让您受益匪浅。
Cumulative Layout Shift (CLS)
下一组建议是针对 Cumulative Layout Shift (CLS),该策略用于衡量网页的视觉稳定性。虽然自 2020 年以来,网络上的 CLS 大幅提升,但大约四分之一的网站仍未达到建议的阈值,因此许多网站仍有很大的提升用户体验的机会。
为从网页加载的任何内容设置明确的尺寸
现有内容在其他内容加载完毕后移动时,通常会发生布局偏移。因此,缓解这一问题的主要方法是尽可能提前预留所有必要的空间。
若要解决因图片大小未调整而导致布局偏移的问题,最直接的方法是明确设置 width
和 height
属性(或等效的 CSS 属性)。不过,根据 HTTP Archive 的数据,72% 的网页至少包含一张未调整大小的图片。如果没有明确的大小,浏览器最初会将默认高度设置为 0px
,当最终加载图片并发现尺寸时,可能会导致明显的布局偏移。这对于全网网络来说是一个巨大的机会,而且与本文中建议的一些其他建议相比,这个机会要少得多。
请务必注意,图片并不是影响 CLS 的唯一因素。布局偏移可能是由通常在网页首次呈现后加载的其他内容(包括第三方广告或嵌入式视频)导致的。aspect-ratio
属性可帮助您应对这种情况。这是一项相对较新的 CSS 功能,可让开发者为图片和非图片元素明确提供宽高比。这样,您就可以设置动态 width
(例如,基于屏幕尺寸),并让浏览器自动计算合适的高度,具体方式与处理具有尺寸的图片时大致相同。
有时,我们无法知道动态内容的确切大小,因为它本质上是动态的。不过,即使您不知道确切大小,您仍然可以采取措施来降低布局偏移的严重程度。设置合理的 min-height
几乎总是比允许浏览器对空元素使用默认高度 0px
更好。使用 min-height
通常也可以轻松解决此问题,因为它仍允许容器扩展至最终内容高度(如果需要),这只是将增长量从全部上限降低到更可接受的水平。
确保网页符合 bfcache 的条件
浏览器会使用一种称为往返缓存(简称 bfcache)的导航机制,直接从内存快照中即时加载浏览器历史记录中之前或之后的网页。
bfcache 在浏览器级别上是一项重要的性能优化,能够完全消除页面加载期间的布局偏移;对于许多网站而言,大多数 CLS 都是发生于页面加载期间。bfcache 的引入使 CLS 提升了 2022 年的最大提升。
尽管如此,仍有许多网站不符合使用 bfcache 的条件,因此在进行大量导航操作时,您也会错失这项免费的网站性能优势。除非您的网页正在加载您不想从内存中恢复的敏感信息,否则您需要确保自己的网页符合条件。
网站所有者应检查其网页是否符合 bfcache 的条件,并找出不符合 bfcache 的条件的所有原因。Chrome 已在开发者工具中提供了 bfcache 测试程序,今年我们计划通过一项执行类似测试的新 Lighthouse 审核和在现场进行衡量的 API 来增强该测试工具。
虽然我们已将 bfcache 纳入 CLS 部分(正如我们到目前为止所见到的最大进步),因此 bfcache 通常也会改进其他核心网页指标。它是许多即时导航功能之一,可显著改善网页导航效果。
避免使用布局诱导 CSS 属性的动画/过渡
布局偏移的另一个常见原因是为元素添加动画效果。例如,从顶部或底部滑入的 Cookie 横幅或其他通知横幅通常对 CLS 有影响。当这些横幅将其他内容推开时,此问题尤其明显,但即使不这样,为它们设置动画效果仍可能会影响 CLS。
虽然 HTTP Archive 数据无法确定地将动画与布局偏移联系起来,但数据显示,如果为任何可能影响布局的 CSS 属性添加动画效果,网页具有“良好”CLS 的可能性要比整体的网页低 15%。某些房源所关联的 CLS 低于其他房源。例如,对于宽度为 margin
或 border
的网页,CLS“不佳”的比率几乎是网页整体被评估为“不佳”的两倍。
这或许不足为奇,因为每次您对任何布局引发的 CSS 属性进行转换或添加动画效果时,都会导致布局偏移,而如果这些布局偏移距离用户互动的间隔不到 500 毫秒,则会影响 CLS。
一些开发者可能出乎意料的是,即使相应元素被提取到常规文档流程之外,情况也是如此。例如,为 top
或 left
添加动画效果的绝对定位元素会导致布局偏移,即使它们不会推动其他内容也是如此。不过,如果您为 transform:translateX()
或 transform:translateY()
添加动画效果,而不是为 top
或 left
添加动画效果,则不会导致浏览器更新页面布局,因此也不会产生任何布局偏移。
长期以来,首选可在浏览器合成器线程上更新的 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 includement 依赖于 CSS
contain
属性,该属性可指示浏览器如何为设置了contain
属性的容器执行布局工作,包括甚至将布局和渲染的范围隔离到 DOM 中的特定根目录。这并不总是一个简单的过程,但通过隔离包含复杂布局的区域,您可以避免为它们执行不必要的布局和渲染工作。
总结
提升网页性能似乎是一项令人望而生畏的任务,特别是考虑到网上有大量指南需要考虑。不过,通过专注于这些建议,您可以有的放矢、有针对性地解决问题,并有望让您网站的核心网页指标获得更理想的效果。
虽然此处列出的建议并非详尽无遗,但根据对网络状态的仔细分析,我们坚信这些建议是网站在 2023 年提高核心网页指标性能的最有效方式。
如果除了上述建议之外,您还可以参阅以下优化指南,了解更多信息:
新的一年快到,让所有人享受更快速的上网体验!希望您的网站能以所有最重要的方式为用户提供快速体验。
摄影:Devin Avery