关于我们衡量 Web 响应速度的计划的更新。
今年早些时候,Chrome Speed Metrics 团队分享了我们正在考虑用于新的响应速度指标的一些想法。我们希望设计一个指标,更好地捕捉单个事件的端到端延迟,并更全面地了解页面在其整个生命周期内的总体响应速度。
在过去的几个月中,我们在此指标上取得了很大进展,我们希望分享关于我们计划如何衡量交互延迟的最新信息,并介绍我们正在考虑的一些具体的聚合选项,以量化网页的总体响应速度。
我们希望获得开发者和网站所有者的反馈,了解这些选项中哪些最能代表其页面的总体输入响应速度。
衡量交互延迟
回顾一下,首次输入延迟 (FID) 指标捕捉了输入延迟的延迟部分。也就是说,从用户与页面交互到事件处理程序能够运行的时间之间的时间。
使用这个新指标,我们计划将其扩展为捕捉完整事件持续时间,从初始用户输入到所有事件处理程序运行后绘制下一帧为止。
我们还计划衡量交互,而不是单个事件。交互是作为同一逻辑用户手势的一部分而分派的事件组(例如:pointerdown
、click
、pointerup
)。
为了衡量来自一组单独事件持续时间的总交互延迟,我们正在考虑两种潜在的方法
- 最大事件持续时间: 交互延迟等于交互组中任何事件的最大单个事件持续时间。
- 总事件持续时间: 交互延迟是所有事件持续时间的总和,忽略任何重叠。
例如,下图显示了一个按键交互,它由一个 keydown
和一个 keyup
事件组成。在此示例中,这两个事件之间存在持续时间重叠。为了衡量按键交互的延迟,我们可以使用 max(keydown duration, keyup duration)
或 sum(keydown duration, keyup duration) - duration overlap
每种方法都有其优点和缺点,我们希望在最终确定延迟定义之前收集更多数据和反馈。
聚合每个页面的所有交互
一旦我们能够衡量所有交互的端到端延迟,下一步就是为页面访问定义一个聚合分数,页面访问可能包含多个交互。
在探索了许多选项之后,我们将选择范围缩小到以下部分中概述的策略,我们目前正在 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]”。我们非常期待听到您的想法!