本文主要从 、 、 、 四个方面优化从而提高加载性能(如下图)
多年来,我们 Google 就如何提高性能向 Web 开发人员提出了很多建议。 虽然这些建议中的每一个单独地都可以提高许多站点的性能,但不可否认,整套建议是压倒性的,而且实际上,任何人或站点都不可能遵循所有这些建议。 除非网络性能是您的日常工作,否则可能并不明显哪些建议会对您的网站产生最大的积极影响。例如,您可能已经读到实施关键 CSS 可以提高加载性能,并且您可能还听说过优化图像很重要。但是,如果您没有时间同时处理这两件事,您将如何决定选择哪一个? 在 Chrome 团队,去年我们一直在尝试回答这个问题:
为了充分回答这个问题,我们不仅要考虑任何给定建议的技术优点,还要考虑影响开发人员实际能够采用这些建议的可能性的人为和组织因素。换句话说,一些建议在理论上可能会产生巨大影响,但实际上很少有站点有时间或资源来实施它们。同样,一些建议很重要,但大多数网站已经在遵循这些做法。
简而言之,我们希望我们的顶级 Web 性能建议列表侧重于:
-
我们认为将的建议
-
的建议
-
的现实建议
在过去的一年里,我们花了很多时间来审核我们提出的全套性能建议,并根据上述三个标准对每一个建议进行评估(定性和定量)。
这篇文章概述了我们为提高每个指标的性能而提出的首要建议。如果您是 Web 性能的新手,或者如果您正在尝试决定什么能给您带来最大的收益,我们认为这些建议是最好的起点。
Largest Contentful Paint(LCP)
我们的第一组建议是针对的,它是负载性能的衡量标准。在三个 Core Web Vitals 指标中,LCP 是数量最多的网站所面临的问题——当今网络上所有网站中只有——所以让我们从这里开始。
了解更多:
确保可以从 HTML 源中发现 LCP 资源
根据HTTP Archive的2022 Web Almanac , 的移动页面将图像作为 LCP 元素,这意味着对于大多数网站来说,要优化 LCP,他们需要确保这些图像可以快速加载。
许多开发人员可能不太清楚的是,加载图像所需的时间只是挑战的一部分。另一个关键部分是图像开始加载之前的时间,HTTP Archive 数据表明这实际上是许多网站被绊倒的地方。
事实上,在 LCP 元素是图像的页面中,的图像具有无法从 HTML 文档源中发现的源 URL 。换句话说,在标准 HTML 属性(<img src="..."> <link rel="preload" href="...">)中找不到这些 URL,这将使浏览器能够快速发现它们并立即开始加载它们。
如果页面需要等待 CSS 或 JavaScript 文件完全下载、解析和处理,然后图像才能开始加载,那么可能已经太晚了。
作为一般规则,如果您的 LCP 元素是图像,则图像的 URL 应该始终可以从 HTML 源中找到。使之成为可能的一些技巧是:
- 使用具有or属性的
<img>元素加载图像。srcsrcsetsrc不要使用需要 JavaScript 才能呈现的非标准属性,因为那样总是会更慢。的页面在data-src. - 首选服务器端呈现 (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 源代码中,如果您的页面在该标签之前的文档中包含十几个<script>标签,则可能需要一段时间才能开始加载图像资源。
解决此问题的最简单方法是通过在加载 LCP 图像的或标记"fetchpriority="high"上设置新属性,向浏览器提供有关哪些资源具有最高优先级的提示。这指示浏览器提前加载它,而不是等待这些脚本完成。
根据 Web Almanac,只有0.03%的符合条件的页面正在利用这个新的 API,这意味着 Web 上的大多数网站都有很多机会以很少的工作来改进 LCP。虽然该fetchpriority属性目前仅在基于 Chromium 的浏览器中受支持,但此 API 是其他浏览器忽略的渐进式增强功能,因此我们强烈建议开发人员立即使用它。
对于非 Chromium 浏览器,确保 LCP 资源优先于其他资源的唯一方法是在文档的前面引用它。再次使用文档中包含大量<script>标签的站点示例<head>,如果您想确保 LCP 资源优先于那些脚本资源,您可以<link rel="preload">在任何这些脚本之前添加一个标签,或者您可以移动这些脚本到下面<img>后面的<body>。虽然这可行,但它不如使用 符合人体工程学fetchpriority,因此我们希望其他浏览器尽快添加支持。
对 LCP 资源进行优先级排序的另一个关键方面是确保您不会执行任何导致其被取消优先级的操作,例如添加loading="lazy"属性。今天,的页面实际上设置loading="lazy"在他们的 LCP 图像上。谨防图像优化解决方案不分青红皂白地将延迟加载行为应用于所有图像。如果他们提供了一种覆盖该行为的方法,请确保将其用于 LCP 图像。如果您不确定哪个图像将成为 LCP,请尝试使用试探法来选择一个合理的候选图像。
推迟非关键资源是另一种有效提高 LCP 资源相对优先级的方法。例如,不支持用户界面的脚本(如分析脚本或社交小部件)可以安全地推迟到load事件触发之后,这确保它们不会与其他关键资源(如 LCP 资源)竞争网络带宽.
总而言之,您应该遵循这些最佳实践以确保尽早加载 LCP 资源并以高优先级加载:
- 添加
fetchpriority="high"到<img>LCP 映像的标签中。如果 LCP 资源是通过<link rel="preload">标签加载的,不要担心,因为您也可以fetchpriority="high"在上面设置! - 切勿
loading="lazy"在 LCP 映像的<img>标签上设置。这样做会降低您的图像的优先级并延迟它开始加载的时间。 - 尽可能延迟非关键资源。通过将它们移动到文档的末尾,对或使用本机延迟加载,或者通过 JavaScript 异步加载它们。
了解更多:
使用 CDN 优化文档和资源 TTFB
前两个建议侧重于确保尽早发现您的 LCP 资源并确定其优先级,以便它可以立即开始加载。这个难题的最后一部分是确保初始文档响应也尽快到达。
浏览器在收到初始 HTML 文档响应的第一个字节之前无法开始加载任何子资源,并且发生得越早,其他一切也可以越早开始发生。
这段时间称为,减少 TTFB 的最佳方法是:
- 在地理位置上尽可能靠近用户提供您的内容
- 缓存该内容,以便可以快速再次提供最近请求的内容。
完成这两件事的最佳方法是。CDN 将您的资源分发到遍布全球的边缘服务器,从而限制了这些资源必须通过线路传输到您的用户的距离。CDN 通常还具有细粒度的缓存控制,可以根据您站点的需要进行定制和优化。
许多开发人员都熟悉使用 CDN 托管静态资产,但 CDN 也可以提供和缓存 HTML 文档,即使是那些动态生成的文档。
根据 Web Almanac,只有的 HTML 文档请求是由 CDN 提供的,这意味着网站有很大的机会要求额外的节省。
配置 CDN 的一些技巧是:
- 考虑增加缓存内容的时间(例如,内容总是新鲜的是否真的很重要?或者它可以过时几分钟吗?)。
- 甚至可以考虑无限期地缓存内容,然后在您进行更新时清除缓存。
- 探索您是否可以将当前在源服务器上运行的动态逻辑移动到(大多数现代 CDN 的一个功能)。
一般来说,任何时候您都可以直接从边缘提供内容(避免访问您的原始服务器),这是性能上的胜利。即使在您确实必须一路返回到原始服务器的情况下,CDN 通常会进行优化以更快地完成该过程,因此无论哪种方式都是双赢。
了解更多:
累积布局偏移 (CLS)
下一组建议是针对的,它是衡量网页视觉稳定性的指标。尽管 CLS自 2020 年以来在网络上有了很大改进,但仍有约四分之一的网站未达到,因此许多网站仍有很大的机会改善其用户体验。
了解更多:
为从页面加载的任何内容设置明确的大小
当现有内容在其他内容完成加载后移动时,通常会发生布局偏移。因此,缓解这种情况的主要方法是尽可能提前预留任何需要的空间。
修复由未调整大小的图像引起的布局偏移的最直接方法是显式设置width和height属性(或等效的 CSS 属性)。然而,根据 HTTP Archive,的页面至少有一张未调整尺寸的图片。如果没有明确的大小,浏览器最初会设置默认高度,0px并且可能会在最终加载图像并发现尺寸时导致明显的布局偏移。这代表了集体网络的巨大机会,而且与本文中建议的其他一些建议相比,这个机会需要的努力要少得多。
同样重要的是要记住,图像并不是 CLS 的唯一贡献者。布局偏移可能是由通常在页面最初呈现后加载的其他内容引起的,包括第三方广告或嵌入式视频。该物业可以帮助解决这个问题。这是一个相对较新的 CSS 功能,允许开发人员明确提供图像和非图像元素的纵横比。这将允许您设置动态width(例如基于屏幕尺寸),并让浏览器自动计算适当的高度,这与它们对具有尺寸的图像所做的方式大致相同。
有时无法知道动态内容的确切大小,因为它本质上是动态的。然而,即使您不知道确切的大小,您仍然可以采取措施来降低布局偏移的严重程度。设置合理min-height的高度几乎总是比允许浏览器对0px空元素使用默认高度更好。使用 min-height通常也是一个简单的修复方法,因为它仍然允许容器在需要时增长到最终的内容高度——它只是将增长量从全部量减少到希望更可容忍的水平。
了解更多:
确保页面符合 bfcache 的条件
浏览器使用一种称为(简称 bfcache)的导航机制,直接从内存快照中立即加载浏览器历史记录中较早或较晚的页面。
bfcache 是一项重要的浏览器级性能优化,它完全消除了页面加载期间的布局变化,对于许多网站来说,这是大部分 CLS 发生的地方。bfcache 的引入导致了我们在 2022 年看到的CLS 的最大改进。
尽管如此,仍有不符合 bfcache 的条件,因此错过了获得大量导航的免费 Web 性能胜利。除非您的页面正在加载您不想从内存中恢复的敏感信息,否则您需要确保您的页面符合条件。
网站所有者应该检查他们的页面是否符合 bfcache 的条件,并解决他们不符合的任何原因。Chrome 已经在 DevTools 中有一个测试器,今年我们计划通过执行类似测试的新 和一个 来增强这里的工具,以在该领域进行测量。
虽然我们在 CLS 部分中包含了 bfcache,但正如我们目前看到的最大收益一样, 通常也会改进其他 Core Web Vitals。它是可用于大幅改进页面导航的众多之一。
了解更多:
- web.dev/bfcache/
- web.dev/bfcache/#te…
- github.com/GoogleChrom…
- chromestatus.com/feature/568…
- calendar.perfplanet.com/2022/fast-i…
避免使用布局诱导 CSS 属性的动画/过渡
布局变化的另一个常见来源是元素动画化。例如,从顶部或底部滑入的 cookie 横幅或其他通知横幅通常是 CLS 的贡献者。当这些横幅将其他内容推开时,这尤其成问题,但即使它们没有,动画化它们仍然会影响 CLS。
虽然 HTTP 存档数据不能最终将动画与布局转换联系起来,但数据确实表明,为任何可能影响布局的 CSS 属性设置动画的页面拥有良好CLS 的可能性比整体页面低 15%。一些属性与比其他属性更差的 CLS 相关联。例如,动画margin或border宽度的页面具有“差”的 CLS,几乎是整体页面被评估为差的比率的两倍。
这也许并不奇怪,因为任何时候你转换或动画任何布局诱导的 CSS 属性,它都会导致布局偏移,如果这些布局偏移不在用户交互的 500 毫秒内,它们将影响 CLS。
一些开发人员可能会感到惊讶的是,即使在元素超出正常文档流的情况下也是如此。例如,绝对定位的元素动画top或left将导致布局变化,即使它们没有推动其他内容。但是,如果不是动画top或者left动画transform:translateX()or transform:translateY(),它不会导致浏览器更新页面布局,因此不会产生任何布局变化。
长期以来,首选可以在浏览器的合成器线程上更新的 CSS 属性动画一直是一种性能最佳实践,因为它将工作转移到了 GPU 上并脱离了主线程。除了作为一般性能最佳实践之外,它还可以帮助改进 CLS。
作为一般规则,永远不要为任何需要浏览器更新页面布局的 CSS 属性设置动画或过渡,除非您这样做是为了响应用户点击或按键(虽然不是hover)。并且只要有可能,更喜欢使用 CSS transform属性的过渡和动画。
Lighthouse 审核将在页面对可能较慢的 CSS 属性进行动画处理时发出警告。
了解更多:
首次输入延迟 (FID)
我们的最后一组建议是针对的,它是衡量页面对用户交互的响应能力的指标。虽然网络上的大多数网站目前在 FID 上得分都很高,但我们在过去记录了 FID 指标的缺点,我们相信网站仍有很多机会提高其对用户交互的整体响应能力。
我们新的Next Paint的交互 ()指标可能是 FID 的继任者,下面的所有建议同样适用于 FID 和 INP。鉴于网站在 INP 上的表现比 FID 差,尤其是在移动设备上,我们鼓励开发人员认真考虑这些响应建议,尽管 FID 是好的。
了解更多:
避免或分解长任务
任务是浏览器执行的任何离散工作。任务包括呈现、布局、解析以及编译和执行脚本。当任务变成(即 50 毫秒或更长)时,它们会阻止主线程快速响应用户输入。
根据 Web Almanac,有大量证据表明开发人员可以采取更多措施来避免或分解长任务。虽然分解长任务可能不像本文中的其他建议那样省力,但它比本文未提供的其他技术省力。
虽然您应该始终努力在 JavaScript 中做尽可能少的工作,但您可以通过将为更小的任务来帮助主线程。您可以通过经常屈服于主线程来实现这一点,以便渲染更新和其他用户交互可以更快地发生。
另一种选择是考虑使用 API,例如和。isInputPending是一个返回布尔值的函数,该值指示用户输入是否未决。如果它返回true,您可以屈服于主线程,以便它可以处理未决的用户输入。
Scheduler API 是一种更高级的方法,它允许您根据优先级系统安排工作,该系统考虑到正在完成的工作是用户可见的还是后台的。
通过分解长任务,您可以让浏览器有更多机会来处理关键的用户可见工作,例如处理交互和任何由此产生的渲染更新。
了解更多:
避免不必要的 JavaScript
毫无疑问:网站使用的 JavaScript 比以往任何时候都多,而且这种趋势看起来不会很快改变。当你发送过多的 JavaScript 时,你正在创建一个任务竞争主线程注意力的环境。这肯定会影响您网站的响应能力,尤其是在关键的启动期间。
然而,这并不是一个无法解决的问题。您确实有一些选择:
- 使用 Chrome DevTools 中的来查找网站资源中未使用的代码。通过减少启动期间所需资源的大小,您可以确保您的网站花费更少的时间来解析和编译代码,从而带来更流畅的初始用户体验。
- 有时,您使用覆盖工具找到的未使用代码会被标记为“未使用”,因为它在启动期间未被执行,但对于将来的某些功能来说仍然是必需的。您可以通过代码拆分将这些代码移动到单独的包中。
如果您使用的是标签管理器,请务必,或者即使它们仍在使用中也是如此。可以清除带有未使用代码的旧标签,以使您的标签管理器的 JavaScript 更小、更高效。
了解更多:
避免大的渲染更新
JavaScript 并不是唯一可以影响网站响应能力的东西。呈现本身可能是一种昂贵的工作——当发生大量呈现更新时,它们可能会干扰您的网站响应用户输入的能力。
优化渲染工作并不是一个简单的过程,它通常取决于您想要实现的目标。即便如此,您还是可以做一些事情来确保您的渲染更新是合理的,并且不会蔓延到长时间的任务中:
- 用于做任何非视觉工作。
requestAnimationFrame()调用在事件循环的渲染阶段处理,如果在此步骤中完成过多工作,渲染更新可能会延迟。您所做的任何工作都必须requestAnimationFrame()严格保留用于涉及渲染更新的任务。 - 。DOM 大小和布局工作的强度相关。当渲染器必须为非常大的 DOM 更新布局时,重新计算其布局所需的工作会显著增加。
- 。CSS 包含依赖于 CSS
contain属性,它向浏览器提供有关如何为contain设置该属性的容器进行布局工作的说明,甚至包括将布局范围和渲染隔离到 DOM 中的特定根目录。这并不总是一个简单的过程,但通过隔离包含复杂布局的区域,您可以避免为它们进行不必要的布局和渲染工作。
了解更多:
- developer.mozilla.org/zhCN/docs/W…
- developer.chrome.com/docs/lighth…
- developer.mozilla.org/zh-CN/docs/…
结论
提高页面性能似乎是一项艰巨的任务,尤其是考虑到网络上有大量指南需要考虑。但是,通过关注这些建议,您可以有针对性地解决问题,并有望为您网站的 Core Web Vitals 带来积极影响。
虽然此处列出的建议绝非详尽无遗,但我们确实相信——基于对网络状况的仔细分析——这些建议是网站在 2023 年提高其核心网络活力性能的最有效方式。
请查看这些优化指南以获取更多信息: