关于衡量 Web 响应能力的计划的最新动态。
今年早些时候,Chrome 速度指标团队分享了我们在考虑制定新的响应速度指标的一些想法。我们希望设计一个指标,以便更好地捕获各个事件的端到端延迟时间,并更全面地了解网页在整个生命周期内的整体响应能力。
在过去几个月中,我们在此指标方面取得了很大进展,在此我们希望与您分享我们计划如何衡量互动延迟时间的最新动态,并介绍一些我们正在考虑的特定汇总选项,以量化网页的总体响应能力。
我们希望获得开发者和网站所有者的反馈,告诉我们哪些选项最能代表其网页的整体输入响应能力。
测量互动延迟时间
回顾一下,First Input Delay (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 小组,并在主题行中添加“[响应性指标]”。我们非常期待收到您的宝贵意见!