你不知道的 Web Vitals(上)

前言

优化用户体验质量一直都是web网站取得成功的关键。
Google 通过与数百万网络开发人员和网站所有者的持续参与和合作,
在浏览器上开发了许多有用的指标和工具,以帮助企业主、营销人员和开发人员等发现改善用户体验的机会。

然而,大量的指标和工具同时给人们带来了很多挑战,比如优先级、清晰度和一致性等等。

web vitals

Google 在 2020年 提出了一个新的概念 web-vitals,这一项举措旨在为质量指标提供统一指南。 Google 认为,这些指标在 web 提供出色的用户体验至关重要。
Google 给的定义是一个良好网站的基本指标 (Essential metrics for a healthy site)。)

Core Web Vitals

衡量用户体验的质量有很多方面, 虽然某些是特定于某站点或者上下文的,但有一些通用的指标对所有网络体验都至关重要 — Core Web Vitals。这样的核心用户体验需求包括页面内容的加载体验、交互性和视觉稳定性等。

Core Web Vitals 是 Web Vitals 的子集,其核心分别是 LCP,FID 和 CLS。
Google 认为没必要每个人都得成为网站性能方面的专家,大部分人只需要关注那些最核心最有价值的指标即可,于是提出了 Core Web Vitals,它是 Web Vitals 的子集,包含 LCP(Largest Contentful Paint),FID(First Input Delay) 和 CLS(Cumulative Layout Shift)。

1. LCP

最大的内容绘制(Largest Contentful Paint), 是一个重要的、以用户为中心的衡量页面感知加载速度的指标,因为它标记了页面加载时间线中页面主要内容可能已加载时的时间点 — 快速的 LCP 有助于让用户确信页面是有用的。

从历史角度看,对 Web 开发人员来说,衡量网页主要内容的加载速度和对用户可见的速度一直是一个挑战。

旧的指标,如 load 或 DOMContent-Loaded 不好,因为它们不一定对应于用户在屏幕上看到的内容。
而较新的,以用户为中心的性能指标,像 First Contentful Paint (FCP) 只捕捉加载体验的最开始。
如果页面显示的是启动画面或加载指示页,那这个时间与用户不是很相关。

过去,我们(指 Google)曾经推荐过相关性能指标,如首次有意义的绘制 (FMP) 和速度指数 (SI)(两者都可在 Lighthouse 中测量),以帮助捕捉初始绘制后的更多加载体验, 但是这些指标很复杂、难以解释,而且经常是错误的 — 这意味着它们仍然无法识别页面的主要内容何时加载。

有时候越简单越好。基于 W3C 网络性能工作组的讨论和谷歌的研究,
我们发现,衡量页面主要内容何时加载的更准确方法 是查看最大元素何时呈现。

相对于页面首次开始加载的时间,LCP 指标报告的是视口内可见最大图像或文本块的渲染时间。

目前在 最大内容绘制(LCP)API 中指定,最大内容绘制的元素类型是:

  1. <img> 元素
  2. <svg> 元素内的 <image> 元素
  3. <video> 元素(使用 poster image)
  4. 通过 url() 函数加载了 background-image 的元素
  5. 包含文本节点或其他内联级文本元素子级的块级元素

以下是一些网站上发生最大内容绘制时的一些示例:

在上面的时间线中,最大的元素随着内容加载而变化。在示例中,新内容被添加到 DOM 并且改变了最大的元素。

虽然延迟加载的内容通常大于页面上已有的内容,但情况并非一定如此。 上面的示例显示了在页面完全加载之前发生的最大内容绘制。


要在 JavaScript 中测量 LCP,可以使用 Largest Contentful Paint API。 以下示例展示了如何创建一个 PerformanceObserver 来侦听最大内容绘制条目并将它们记录到控制台。

const p_ob = new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('LCP candidate:', entry.startTime, entry);
  }
})

p_ob.observe({type: 'largest-contentful-paint', buffered: true});
复制代码

tips:

在上面的例子中,每个记录的最大内容绘制条目代表当前的 LCP 候选。 通常,发出的最后一个条目的 startTime 值是 LCP 值 — 但是,情况并非总是如此。并非所有最大内容绘制 entries都适用于测量 LCP。 另外:Performance-Observer LCP相关 API 在苹果浏览器支持并不友好。

2. FID

首次输入延迟(First Input Delay), 是衡量负载响应能力的一个重要的、以用户为中心的指标,因为它量化了用户尝试与无响应页面交互时的体验 — 低 FID 有助于确保页面可用。

我们都知道给人留下一个良好的第一印象是多么重要,当然了,这在 web 上建立体验感时也同等很重要。

良好的第一印象可以决定某人成为忠实用户还是离开并永远不会回来。问题是,什么才能给人留下好印象,你如何衡量你可能会给用户留下什么样的印象?第一印象可以有很多不同的形式 — 例如我们对网站的设计和视觉吸引力有第一印象,对其速度和响应能力也有第一印象。

虽然很难通过 Web API 来衡量用户对网站设计的喜爱程度,但衡量其速度和响应能力却可以尝试。

用户对网站加载速度的第一印象可以被 LCP 衡量,然而,网站在屏幕上绘制像素的速度有多快只是其中的一部分,同样重要的是当用户尝试与这些像素进行交互时,你的网站的响应能力如何。

首次输入延迟 (FID) 指标有助于衡量用户对网站交互性和响应性的第一印象。

FID 测量是从用户第一次与页面交互(即当单击链接、点击按钮或使用自定义的或由 JavaScript 驱动的控件)到浏览器真正能够开始处理事件处理程序以回应这种交互的时间。

FID 仅测量事件处理中的“延迟”。 它不会测量事件处理时间本身,也不会测量浏览器在运行事件处理程序后更新 UI 所花费的时间。 虽然这段时间确实会影响用户体验,但将其作为 FID 的一部分会刺激开发人员去异步响应事件 — 这种虽可以改善指标但可能会使体验变得更糟。

下面分析一下典型的网页加载时间线:

上面可视化显示了一个 web 页面加载过程,它对资源(最有可能是 CSS 和 JS 文件)发出了几个网络请求,并等这些资源下载完成后在主线程上进行处理,它会导致主线程暂时处于忙碌状态。

首次输入延迟通常发生在首次内容绘制 (FCP) 和可交互时间 (TTI) 之间,因为页面已经呈现了一些内容,但还不能进行可靠地交互。

下面或许更清晰的表达了这一点

你可能已经注意到 FCP 和 TTI 之间有相当长的时间(包括 long tasks),如果用户在此期间尝试与页面交互(例如单击链接),在收到点击和主线程能够处理响应之间会有一个延迟。

因为输入事件发生在浏览器正在运行任务的过程中,它必须等到任务完成才能响应输入事件。它必须等待的时间是页面上的 FID 值。当然了,如果用户在主线程空闲期间与页面进行了交互,浏览器可能会立即做出响应。


FID 是一项只能在操作现场测量的指标,因为它需要真实用户与您的页面进行交互。
要在 JavaScript 中测量 FID,您可以使用 Event Timing API。 以下示例显示了如何创建一个 PerformanceObserver 来侦听第一个输入条目并将它们记录到控制台:

const p_ob = new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    const delay = entry.processingStart - entry.startTime;
    console.log('FID candidate:', delay, entry);
  }
})

p_ob.observe({type: 'first-input', buffered: true});

复制代码


另外,对于 FID 的更多细节可以参考 文献 FID, 比如为什么只考虑第一个输入? 什么才算作真正的第一次输入?

3. CLS

累积布局偏移(Cumulative Layout Shift), 测量视觉稳定性 并量化可见页面内容的意外布局偏移量。

你有没有过这样的体验。您是否曾经在线阅读过一篇文章,当页面上的某些内容突然发生变化时,在没有警告的情况下,文本移动了,从当前位置丢失了。或者更糟糕的是:您正要点击一个链接或一个按钮,但在您的手指落地之前的瞬间 — 突然链接移动了,你最终点击了其他按钮。

大多数情况下,这些体验只是令人讨厌,但在某些情况下,它们可能会造成真正的伤害。

页面内容的意外移动通常是因为资源是异步加载的,或者 DOM 元素被动态添加到现有内容上方的页面中。罪魁祸首可能是尺寸未知的图像或视频,动态调整自身大小的第三方广告或部件。

使这个问题更糟糕的是,网站在开发中的运作方式通常与用户的体验方式大不相同。个性化或第三方内容通常在开发中的表现与在生产中的表现不同,
测试的图片通常已经缓存在开发者的浏览器中,并且在本地运行的 API 调用通常非常快,以至于延迟并不明显。

累积布局偏移 (CLS) 指标通过测量真实用户发生的频率来帮助您解决此问题。

CLS (累计布局偏移) 是衡量页面整个生命周期内发生的每个意外布局偏移的最大布局偏移分数的度量。测量在页面的整个生命周期中发生的每个意外的样式移动所造成的布局偏移分数的总和。

Layout shifts被 Layout Instability API 定义,每当视口中可见的元素更改其起始位置时,它都会报告在两帧之间 Layout shift entries(例如,在默认模式下的顶部和左侧位置)。这样的元素被认为是不稳定的元素。

请注意,仅当现有元素起始位置更改时才会发生 Layout shifts, 如果将新元素添加到 DOM 或 现有元素更改大小,则不会算作布局偏移(只要变化不会导致其他可见元素起始位置的更改)。

CLS 计算方式:元素位移分数 (Layout Shift Score) = 影响范围 (Impact Fraction) * 移动距离 (Distance Fraction)

上面图例来讲就是,影响范围 (红色) 占比 Viewport 75% ,箭头 (紫色) 移动占 Viewport 的 height 25%,故 0.75 * 0.25 = 0.1875。


在 JavaScript 中测量 CLS,您可以使用 Layout Instability API。 下面的例子展示了如何创建一个 PerformanceObserver,它监听意外的 layout-shift entries,将它们分组到会话中,并在它发生变化时记录最大会话值。

let clsValue = 0;
let clsEntries = [];

let sessionValue = 0;
let sessionEntries = [];

const p_ob = new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    // Only count layout shifts without recent user input.
    if (!entry.hadRecentInput) {
      const firstSessionEntry = sessionEntries[0];
      const lastSessionEntry = sessionEntries[sessionEntries.length - 1];

      // If the entry occurred less than 1 second after the previous entry and
      // less than 5 seconds after the first entry in the session, include the
      // entry in the current session. Otherwise, start a new session.
      if (sessionValue &&
          entry.startTime - lastSessionEntry.startTime < 1000 &&
          entry.startTime - firstSessionEntry.startTime < 5000) {
        sessionValue += entry.value;
        sessionEntries.push(entry);
      } else {
        sessionValue = entry.value;
        sessionEntries = [entry];
      }

      // If the current session value is larger than the current CLS value,
      // update CLS and the entries contributing to it.
      if (sessionValue > clsValue) {
        clsValue = sessionValue;
        clsEntries = sessionEntries;

        // Log the updated value (and its entries) to the console.
        console.log('CLS:', clsValue, clsEntries)
      }
    }
  }
})

p_ob.observe({type: 'layout-shift', buffered: true});

复制代码



这些指标都以用户为中心的重要结果为基准,可进行现场测量,并具有等价的实验性指标。例如,虽然 LCP 是页面加载指标的质量天花板,但它也高度依赖于首次内容绘制 (FCP) 和首字节时间 (TTFB),这对于监控和改进仍然至关重要。

总结

这里主要介绍 Google 提出的 core-web-vitals 三个核心 web 性能指标,虽然这三个指标是被定义为最核心的,但是在实际的 web 性能监控与统计分析中,仅仅这三个指标往往是不够的,还需要结合实际情况加入更多的性能指标元素。

不可否认的是,Google 在 web 标准化统一化方向一直在做努力。


vx公众号: 前端小菜鸟001

文章第一时间会发在公众号

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享