需要反馈:实验性响应速度指标

关于我们衡量 Web 响应速度的计划的更新。

今年早些时候,Chrome Speed Metrics 团队分享了我们正在考虑用于新的响应速度指标的一些想法。我们希望设计一个指标,更好地捕捉单个事件的端到端延迟,并更全面地了解页面在其整个生命周期内的总体响应速度。

在过去的几个月中,我们在此指标上取得了很大进展,我们希望分享关于我们计划如何衡量交互延迟的最新信息,并介绍我们正在考虑的一些具体的聚合选项,以量化网页的总体响应速度。

我们希望获得开发者和网站所有者的反馈,了解这些选项中哪些最能代表其页面的总体输入响应速度。

衡量交互延迟

回顾一下,首次输入延迟 (FID) 指标捕捉了输入延迟的延迟部分。也就是说,从用户与页面交互到事件处理程序能够运行的时间之间的时间。

使用这个新指标,我们计划将其扩展为捕捉完整事件持续时间,从初始用户输入到所有事件处理程序运行后绘制下一帧为止。

我们还计划衡量交互,而不是单个事件。交互是作为同一逻辑用户手势的一部分而分派的事件组(例如:pointerdownclickpointerup)。

为了衡量来自一组单独事件持续时间的总交互延迟,我们正在考虑两种潜在的方法

  • 最大事件持续时间: 交互延迟等于交互组中任何事件的最大单个事件持续时间。
  • 总事件持续时间: 交互延迟是所有事件持续时间的总和,忽略任何重叠。

例如,下图显示了一个按键交互,它由一个 keydown 和一个 keyup 事件组成。在此示例中,这两个事件之间存在持续时间重叠。为了衡量按键交互的延迟,我们可以使用 max(keydown duration, keyup duration)sum(keydown duration, keyup duration) - duration overlap

A
diagram showing interaction latency based on event durations

每种方法都有其优点和缺点,我们希望在最终确定延迟定义之前收集更多数据和反馈

聚合每个页面的所有交互

一旦我们能够衡量所有交互的端到端延迟,下一步就是为页面访问定义一个聚合分数,页面访问可能包含多个交互。

在探索了许多选项之后,我们将选择范围缩小到以下部分中概述的策略,我们目前正在 Chrome 中收集关于每种策略的真实用户数据。我们计划在有时间收集足够的数据后发布我们的发现结果,但我们也正在寻求网站所有者的直接反馈,了解哪种策略最能准确反映其页面上的交互模式。

聚合策略选项

为了帮助解释以下每个策略,请考虑一个示例页面访问,该页面访问由四个交互组成

交互 延迟
点击 120 毫秒
点击 20 毫秒
按键 60 毫秒
按键 80 毫秒

最差交互延迟

页面上发生的最大单个交互延迟。考虑到上面列出的示例交互,最差交互延迟将为 120 毫秒。

预算策略

用户体验研究表明,用户可能不会将低于某些阈值的延迟视为负面因素。基于这项研究,我们正在考虑对每种事件类型使用以下阈值的几种预算策略

交互类型 预算阈值
点击/触摸 100 毫秒
拖动 100 毫秒
键盘 50 毫秒

以下每个策略都将仅考虑每个交互超过预算阈值的延迟。使用上面的示例页面访问,超出预算的金额将如下所示

交互 延迟 超出预算的延迟
点击 120 毫秒 20 毫秒
点击 20 毫秒 0 毫秒
按键 60 毫秒 10 毫秒
按键 80 毫秒 30 毫秒

超出预算的最差交互延迟

超出预算的最大单个交互延迟。使用上面的示例,分数将为 max(20, 0, 10, 30) = 30 ms

超出预算的总交互延迟

所有超出预算的交互延迟的总和。使用上面的示例,分数将为 (20 + 0 + 10 + 30) = 60 ms

超出预算的平均交互延迟

超出预算的总交互延迟除以交互总数。使用上面的示例,分数将为 (20 + 0 + 10 + 30) / 4 = 15 ms

高分位数近似

作为计算超出预算的最大交互延迟的替代方法,我们还考虑使用高分位数近似,对于具有大量交互且可能更可能出现大型异常值的网页,这应该更公平。我们已经确定了我们喜欢的两种潜在的高分位数近似策略

  • 选项 1: 跟踪超出预算的最大和第二大交互。每 50 个新交互后,从之前的 50 个集合中删除最大的交互,并添加当前 50 个集合中最大的交互。最终值将是剩余的超出预算的最大交互。
  • 选项 2: 计算超出预算的前 10 个最大交互,并根据交互总数从该列表中选择一个值。给定 N 个总交互,选择第 (N / 50 + 1) 个最大值,或者对于交互次数超过 500 的页面,选择第 10 个值。

在 JavaScript 中衡量这些选项

以下代码示例可用于确定上面介绍的前三个策略的值。请注意,目前尚无法在 JavaScript 中衡量页面上的交互总数,因此此示例不包括超出预算的平均交互策略或高分位数近似策略。

const interactionMap = new Map();

let worstLatency = 0;
let worstLatencyOverBudget = 0;
let totalLatencyOverBudget = 0;

new PerformanceObserver((entries) => {
  for (const entry of entries.getEntries()) {
    // Ignore entries without an interaction ID.
    if (entry.interactionId > 0) {
      // Get the interaction for this entry, or create one if it doesn't exist.
      let interaction = interactionMap.get(entry.interactionId);
      if (!interaction) {
        interaction = {latency: 0, entries: []};
        interactionMap.set(entry.interactionId, interaction);
      }
      interaction.entries.push(entry);

      const latency = Math.max(entry.duration, interaction.latency);
      worstLatency = Math.max(worstLatency, latency);

      const budget = entry.name.includes('key') ? 50 : 100;
      const latencyOverBudget = Math.max(latency - budget, 0);
      worstLatencyOverBudget = Math.max(
        latencyOverBudget,
        worstLatencyOverBudget,
      );

      if (latencyOverBudget) {
        const oldLatencyOverBudget = Math.max(interaction.latency - budget, 0);
        totalLatencyOverBudget += latencyOverBudget - oldLatencyOverBudget;
      }

      // Set the latency on the interaction so future events can reference.
      interaction.latency = latency;

      // Log the updated metric values.
      console.log({
        worstLatency,
        worstLatencyOverBudget,
        totalLatencyOverBudget,
      });
    }
  }
  // Set the `durationThreshold` to 50 to capture keyboard interactions
  // that are over-budget (the default `durationThreshold` is 100).
}).observe({type: 'event', buffered: true, durationThreshold: 50});

反馈

我们希望鼓励开发者在其网站上试用这些新的响应速度指标,并告知我们您是否发现任何问题。

请将关于此处概述的方法的任何一般反馈通过电子邮件发送到 web-vitals-feedback Google 网上论坛,并在主题行中注明“[Responsiveness Metrics]”。我们非常期待听到您的想法!