多年来,网络社区积累了丰富的网络性能优化知识。虽然任何一项优化都可以提升许多网站的性能,但如果同时进行所有优化,可能会让人感到不知所措。实际上,只有部分优化措施适用于任何给定网站。
除非您是网站性能方面的专业人士,否则可能很难确定哪些优化措施对您的网站影响最大。您可能没有时间全部完成,因此请务必问自己:您可以选择哪些最具影响力的优化措施来提升用户体验?
关于性能优化的真相是:您不能仅根据技术优势来评判优化效果。您还需要考虑人力和组织因素,这些因素会影响您实现任何给定优化的可能性。从理论上讲,某些性能改进可能具有巨大影响,但在现实中,很少有开发者有时间或资源来实现这些改进。另一方面,可能有几乎所有人都已在遵循的效果极佳的最佳实践。本指南介绍了以下 Web 性能优化措施:
- 具有最大的现实影响
- 与大多数网站相关且适用
- 对大多数开发者而言是否切合实际
总的来说,这些是最切实有效的方法,可帮助您改进 Core Web Vitals 指标。如果您刚开始接触网页性能,或者您仍在确定什么能带来最大的投资回报率,那么建议您从该指南开始。
Interaction to Next Paint (INP)
作为最新的 Core Web Vitals 指标,Interaction to Next Paint (INP) 有许多值得改进的地方。不过,由于与其已弃用的前身相比,达到“良好”体验阈值的网站更少,因此您可能是众多首次学习如何优化互动响应能力的开发者之一。不妨先了解这些必备技巧,以便以最有效的方式提升 INP。
1. 经常使用收益率,将耗时较长的任务分离开来
任务是浏览器执行的任何离散工作,包括渲染、布局、解析、编译或执行脚本。当一个任务的时长超过 50 毫秒时,该任务就变成了长时间运行的任务。耗时较长的任务会带来问题,因为它们可能阻止主线程快速响应用户互动。
虽然您应始终努力尽量减少在 JavaScript 中完成的工作,但您可以通过分解长时间运行的任务来帮助主线程执行任务。为此,您可以经常让出主线程,以便更快地进行渲染更新和其他用户互动。
借助 Scheduler API,您可以使用优先级系统将工作加入队列。具体而言,scheduler.yield() API 会拆分长任务,同时确保能够在不放弃任务队列中的位置的情况下处理互动。
通过分解冗长的任务,浏览器有更多机会来负责阻碍用户的关键工作。
2. 避免使用不必要的 JavaScript
网站所发送的 JavaScript 比以往任何时候都多,而且这种趋势似乎不会改变。如果您提交的 JavaScript 过多,就会造成任务争夺主线程的注意力。这可能会影响网站的响应速度,尤其是在关键的启动期间。
不过,这并不是一个无法解决的问题,您可以采取以下措施:
- 使用基准广泛提供的 Web 平台功能,而不是冗余的基于 JavaScript 的实现。
- 使用 Chrome 开发者工具中的覆盖率工具查找脚本中未使用的代码。通过缩减启动期间所需资源的大小,您可以确保网页花在解析和编译代码上的时间更少,从而提供更流畅的初始用户体验。
- 使用代码分块为初始渲染不需要但日后仍会使用的代码创建单独的软件包。
- 如果您使用的是跟踪代码管理器,请定期优化代码。您可以移除包含未使用的代码的旧版代码,以缩减跟踪代码管理器的 JavaScript 占用空间。
3. 避免大规模渲染更新
JavaScript 执行只是影响网站响应速度的众多因素之一。呈现本身就是一项耗费巨大的工作,在进行大型呈现更新时,您的网站对用户互动的响应速度可能会更慢。
优化渲染工作并非一个简单的过程,具体取决于您要实现的目标。即便如此,您也可以采取以下措施来确保渲染任务不会变成长任务:
- 重新整理 JavaScript 代码中的 DOM 读写操作,以避免强制布局和布局抖动。
- 使 DOM 大小保持小巧。DOM 大小与布局工作强度相关。当渲染程序必须更新非常大的 DOM 的布局时,重新计算其布局所需的工作量可能会大幅增加。
- 使用 CSS 组件延迟渲染屏幕外的 DOM 内容。这并不总是简单明了,但通过隔离包含复杂布局的区域,您可以避免不必要的布局和渲染工作。
Largest Contentful Paint (LCP)
Largest Contentful Paint (LCP) 是开发者最难把控的核心 Web 指标:Chrome 用户体验报告中40%的网站未达到建议的 LCP 阈值,无法提供良好的用户体验。Chrome 团队建议使用以下技术来最有效地缩短 LCP。
1. 确保 LCP 资源可从 HTML 源中发现并获得优先级
Chrome 团队注意到有关网页上的 LCP 的以下事项:
- 根据 HTTP Archive 的 2022 年网络年鉴,72% 的移动网页将图片作为 LCP 元素。
- 通过对 Chrome 中的真实用户数据进行的分析,我们发现,大多数 LCP 表现不佳的来源在下载 LCP 映像上所花的 LCP 映像的时间只有不到 10%。
- 在 LCP 较差的网页中,75 百分位数的 LCP 图片在客户端上的加载延迟时间为 1,290 毫秒,这超过了快速体验预算的一半。
- 在 LCP 元素为图片的网页中,39% 的图片的来源网址在初始 HTML 响应中不可检测(例如
<img src="...">
或<link rel="preload" href="...">
),这会导致浏览器的预加载扫描器无法尽快发现这些图片。 - 根据《Web Almanac》的资料,只有 0.03% 的符合条件的网页利用
fetchpriority
HTML 属性为资源提供了更高的优先级,其中包括那些可以事半功倍地改善网页 LCP 的资源。
这些统计数据表明,开发者有很大的机会来缩短 LCP 映像的资源加载延迟和资源加载时长。
如果资源加载延迟是问题所在,请务必注意,如果网页需要等待 CSS 或 JavaScript 完全加载后才能开始加载图片,那么可能已经太晚,无法实现良好的 LCP。此外,您还可以使用 fetchpriority
HTML 属性重新调整 LCP 图片的优先级,以便其获得更多带宽,从而加快加载速度,缩短资源加载时长。
如果您的 LCP 元素是图片,则应在 HTML 响应中发现图片的网址,以缩短其资源加载延迟时间。以下是一些有助于实现这一目标的提示:
- 使用带有
src
或srcset
属性的<img>
元素加载图片。请勿使用需要 JavaScript 才能呈现的非标准属性(例如data-src
),因为这类属性的速度始终较慢。9% 的网页会将 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 资格条件。网页不符合 bfcache 条件的常见原因是,它们使用 no-store
缓存指令进行传送或具有 unload
事件监听器。
恢复完全呈现的网页不仅可以提升加载性能,还可以提高布局稳定性。如需详细了解 bfcache 以及它在提高 CLS 方面的有效性,请参阅确保网页符合 bfcache 使用条件部分。
浏览器支持
预渲染用户下次访问的网页是显著提升 LCP 性能的另一种有效方法,可通过 Speculation Rules API 实现。不过,要想实现这些优势,请确保预渲染正确的网页。错误的推测会浪费服务器和客户端上的资源,从而影响性能。因此,您对下一页的预期越不确定,就越应谨慎地预渲染该页面。当存在疑虑时,您的分析数据可让您信心十足地预呈现最有可能下次访问的网页。
3. 使用 CDN 优化 TTFB
之前的建议侧重于即时导航,可为用户提供尽可能出色的体验,但在某些情况下,bfcache 和推测性加载技术可能不适用。假设有用户访问了指向您网站的跨源链接,最初的 HTML 文档响应有效地阻止了 LCP。浏览器在收到响应的第一个字节之前,无法开始加载任何子资源。越早完成,其他所有工作就能越早开始。
该时间称为第一字节时间 (TTFB)。缩短 TTFB 的最佳方法是:
- 在地理位置上尽可能靠近用户的位置发布内容。
- 缓存该内容,以便在近期再次请求该内容时可以快速提供该内容。
要同时实现这两点,最佳方式是使用 CDN。CDN 会将您的资源分发到全球各地的边缘服务器,从而限制这些资源通过网络传输到用户的距离。CDN 通常还具有精细的缓存控制功能,可根据您网站的需求进行调整。
CDN 还可以分发和缓存 HTML 文档,但根据《网络年鉴》的统计,只有 29% 的 HTML 文档请求是通过 CDN 分发的。这意味着,网站有很大机会进一步节省开支。
关于配置 CDN 的一些提示包括:
- 缓存静态 HTML 文档,即使只是短时间。例如,内容是否始终保持新鲜度很重要吗?或者可以延迟几分钟吗?
- 探索是否可以将在源服务器上运行的动态逻辑移至边缘(这是大多数新型 CDN 的一项功能)。
每当您可以直接从边缘传送内容并避免发送到源服务器时,性能就会得到提升。即使您必须一直访问到源站,CDN 通常也会经过优化,以便更快地完成访问,因此无论哪种方式,您都能获益。
Cumulative Layout Shift (CLS)
Cumulative Layout Shift (CLS) 用于衡量网页的视觉稳定性。虽然 CLS 是大多数网站往往都能取得良好效果的指标,但有大约四分之一的网站仍未达到建议的阈值,因此许多网站仍有很大的机会改进用户体验。
1. 为从网页加载的任何内容设置明确的尺寸
布局偏移通常发生在其他内容加载完毕后现有内容移动时。提高 CLS 的主要方法是尽可能提前预留所需空间。
要解决因图片大小不合适而导致的布局偏移,最佳方法是明确设置 width
和 height
属性或其等效的 CSS 属性。72% 的网页至少有一张未调整大小的图片。如果没有明确的尺寸,这些图片的初始高度为 0px
,这可能会导致在这些图片加载并浏览器发现其尺寸时,布局发生偏移。这对集体网络来说是一个巨大的机遇,而且相较于本指南中建议的其他一些做法,抓住这个机遇所需的工作量更少。
图片并非 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 Archive 数据无法确切地将动画与布局偏移联系起来,但数据确实表明,与整体网页相比,如果网页为任何可能会影响布局的 CSS 属性添加动画,CLS 达到“良好”水平的可能性会降低 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 审核会发出警告。
总结
提升网页性能可能看起来很难,尤其是考虑到网络上有大量的指导信息需要参考。不过,通过关注这份简短的最有效的最佳实践列表,您可以重新专注于解决问题,并有望为您网站的核心网页指标更进一步。
如果您想采取上述优化措施之外的措施,请参阅以下指南了解详情:
附录:更新日志
我们会在此处跟踪本文档的重大变更,以便说明热门建议何时发生变化以及原因。
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 大会演示文稿,查看视频摘要。