在实验室手动诊断慢速交互

了解如何将您的现场数据带到实验室,通过手动测试重现并找出慢速交互背后的原因。

发布时间:2023 年 5 月 9 日

优化交互到下次绘制 (INP) 的一个挑战性部分是弄清楚是什么导致了 INP 不佳。有很多潜在原因,例如在主线程上安排许多任务的第三方脚本、大型 DOM 大小、开销大的事件回调以及其他罪魁祸首。

改进 INP 可能很困难。首先,您必须知道哪些交互导致了页面的 INP。如果您不知道您网站上的哪些交互从真实用户的角度来看往往是最慢的,请阅读在现场查找慢速交互。一旦您有了现场数据来指导您,您就可以在实验室工具中手动测试这些特定的交互,以找出这些交互速度缓慢的原因。

如果您没有现场数据怎么办?

拥有现场数据至关重要,因为它可以节省您大量时间来弄清楚哪些交互需要优化。但是,您可能处于没有现场数据的位置。如果这种情况描述了您的情况,那么仍然可以找到需要改进的交互,尽管这需要付出更多的努力和不同的方法。

总阻塞时间 (TBT) 是一项实验室指标,用于评估页面加载期间的响应速度,并且它与 INP 非常相关。如果您的页面 TBT 很高,则可能表明您的页面在页面加载时对用户交互的响应速度可能不是很快。

要找出您页面的 TBT,您可以使用Lighthouse。如果页面的 TBT 很高,则主线程很可能在页面加载期间过于繁忙,这可能会影响页面在页面生命周期的关键时期内的响应速度。

要在页面加载后查找慢速交互,您可能需要其他类型的数据,例如您可能已经在网站分析中识别出的常见用户流程。例如,如果您在电子商务网站上工作,常见的用户流程将是用户在将商品添加到在线购物车并结账时采取的操作。

无论您是否有现场数据,下一步都是手动测试和重现慢速交互,因为只有当您能够重现慢速交互时,您才能修复它。

在实验室中重现慢速交互

您可以通过手动测试在实验室中重现慢速交互的方法有很多,但以下是您可以尝试的框架。

DevTools 性能面板实时指标

DevTools 性能分析器是诊断已知速度慢的交互的推荐方法,但是当您不知道哪些交互存在问题时,可能需要花费时间来识别慢速交互。

当您首次打开“性能”面板时,您将看到实时指标视图。在您进入更详细的性能分析器之前,可以使用它快速尝试许多交互以查找有问题的内容。当您交互时,诊断数据将出现在“交互”日志中(INP 交互突出显示)。可以展开这些交互以获取阶段细分

How logs for interactions appear in the live metrics screen of the Performance panel.
“性能”面板的实时指标屏幕。

虽然实时指标视图有助于识别慢速交互,并提供一些细节来帮助您调试 INP,但您可能仍然需要使用性能分析器来诊断慢速交互,因为它提供了您需要浏览网站生产代码以查找慢速交互背后原因的详细数据。

记录跟踪

Chrome 的性能分析器是诊断和排除慢速交互故障的推荐工具。要在 Chrome 的性能分析器中分析交互,请按照以下步骤操作

  1. 打开您要测试的页面。
  2. 打开 Chrome DevTools 并转到性能面板。
  3. 单击面板左上角的记录按钮以开始跟踪。
  4. 执行您要排除故障的交互。
  5. 再次单击记录按钮以停止跟踪。

当分析器填充后,首先要查看的地方应该是分析器顶部的活动摘要。活动摘要在顶部显示红色条,表示记录中发生了长时间任务。这使您可以快速放大问题区域。

The activity summary as it appears near the top of the performance panel of Chrome DevTools. The activity displayed is mostly from JavaScript that causes a long task, which is highlighted in red above the flame chart.
Chrome 性能分析器顶部的活动摘要。长时间任务在活动火焰图上方的红色突出显示。在本例中,大量的脚本工作是导致长时间任务中大部分工作的原因。

您可以通过在活动摘要中拖动并选择区域来快速关注问题区域。您可以选择使用分析器中的面包屑功能来帮助您缩小时间线并忽略不相关的活动。

一旦您专注于交互发生的位置,交互轨道可以帮助您将交互与下方主线程轨道中发生的活动对齐

An interaction as visualized in the performance panel of Chrome DevTools. An interactions track above the main thread track shows the duration of an interaction, which can be lined up with the main thread activity beneath it.
在 Chrome DevTools 的性能分析器中分析的交互。交互轨道显示一系列与点击交互相对应的事件。“交互”轨道条目跨越负责驱动交互的任务。

您可以通过将鼠标悬停在交互轨道中的交互上来获取有关交互哪个部分最长的更多详细信息

A hover tooltip for an interaction as shown in the performance panel of Chrome DevTools. The tooltip shows how much time was spent in the interaction, and in which part, including the interaction's input delay, processing duration, and presentation delay.
当鼠标悬停在性能面板的交互轨道中的交互上时显示的工具提示。工具提示显示在交互的每个部分花费了多少时间。

交互的条纹部分表示交互超过 200 毫秒的时间,这是页面 INP“良好”阈值的上限。列出的交互部分是

  1. 输入延迟—由左侧的须线可视化。
  2. 处理时长—由左右须线之间的实心块可视化。
  3. 呈现延迟—由右侧的须线可视化。

从这里开始,就需要更深入地挖掘导致慢速交互的问题,这将在本指南的后面部分介绍。

如何识别交互的哪个部分速度缓慢

交互由三个部分组成:输入延迟、处理时长和呈现延迟。您如何优化交互以降低页面的 INP 取决于哪个部分花费的时间最多。

如何识别长时间输入延迟

输入延迟可能会导致高交互延迟。输入延迟是交互的第一部分。这是从操作系统首次接收到用户操作到浏览器能够开始处理该交互的第一个事件处理程序回调的时间段。

可以在 Chrome 性能分析器中通过在交互轨道中找到交互来完成识别输入延迟。左侧须线的长度表示交互的输入延迟部分,精确值可以在将鼠标悬停在性能分析器中的交互上时在工具提示中找到。

输入延迟永远不可能为零,但您确实可以控制输入延迟的长度关键是弄清楚主线程上是否有工作正在运行,从而阻止您的回调尽快运行。

Input delay as depicted in Chrome's performance panel. The start of the interaction comes significantly before the event callbacks because of increased input delay due to a timer firing from a third-party script.
由第三方脚本的计时器触发的任务引起的输入延迟。交互轨道中显示的交互中须线的左侧部分可视化了输入延迟。

在上图中,当用户尝试与页面交互时,第三方脚本的任务正在运行,因此延长了输入延迟。延长的输入延迟会影响交互的延迟,因此可能会影响页面的 INP。

如何识别长时间处理时长

事件回调在输入延迟后立即运行,它们完成所需的时间称为处理时长。如果事件回调运行时间过长,它们会延迟浏览器呈现下一帧,并可能显着增加交互的总延迟。长时间处理时长可能是计算开销大的第一方或第三方 JavaScript(在某些情况下,两者兼有)造成的。在性能分析器中,这由交互轨道中交互的实心部分表示。

A depiction of event callback tasks in Chrome's performance panel. The hover tooltip over the interaction on the timeline reveals a long processing duration.
响应点击交互而运行的事件回调,如 Chrome DevTools 的性能分析器中所示。请注意高处理时长。

可以通过在特定交互的跟踪中观察以下内容来完成查找开销大的事件回调

  1. 确定与事件回调关联的任务是否为长时间任务。为了更可靠地在实验室环境中显示长时间任务,您可能需要在性能面板中启用 CPU 节流,或者连接低端到中端 Android 设备并使用远程调试
  2. 如果运行事件回调的任务是长时间任务,请查找调用堆栈中的事件处理程序条目(例如,名称类似于 Event: click 的条目),这些条目的右上角有一个红色三角形。

您可以尝试以下策略之一来减少交互的处理时长

  1. 尽可能少做工作。 在开销大的事件回调中发生的所有事情都是绝对必要的吗?如果不是,请考虑尽可能完全删除该代码,或者如果可以,则将其执行推迟到稍后的时间点。您还可以利用框架功能来获得帮助。例如,React 的memoization 功能可以在组件的 props 没有更改时跳过不必要的渲染工作。
  2. 将事件回调中非渲染工作推迟到稍后的时间点。 长时间任务可以通过让步于主线程来分解。每当您让步于主线程时,您都在结束当前任务的执行,并将剩余的工作分解为单独的任务。这使渲染器有机会处理在事件回调中较早执行的对用户界面的更新。如果您恰好正在使用 React,它的转换功能可以为您做到这一点。

这些策略应该能够帮助您优化事件回调,使其运行时间更短。

如何识别呈现延迟

长时间输入延迟和处理时长并不是导致 INP 不佳的唯一原因。有时,即使少量事件回调代码中发生的渲染更新也可能开销很大。浏览器呈现用户界面中的视觉更新以反映交互结果所需的时间称为呈现延迟

Rendering work as visualized in the performance panel of Chrome DevTools. The rendering work occurs after the event callback in order to paint the next frame.
Chrome 性能分析器中显示的渲染任务。右侧的须线可视化了呈现延迟的长度。

渲染工作通常由样式重新计算、布局、绘制和合成等任务组成,并在分析器的火焰图中以紫色和绿色块表示。总呈现延迟由交互轨道中交互的右侧须线表示。

在所有可能导致高交互延迟的原因中,呈现延迟可能是最难排除故障和修复的。过多的渲染工作可能是由以下任何原因引起的

  • 大型 DOM 大小。 更新页面呈现所需的渲染工作通常会随着页面 DOM 大小的增加而增加。有关更多信息,请阅读大型 DOM 大小如何影响交互性以及您可以采取哪些措施
  • 强制回流。 当您在 JavaScript 中将样式更改应用于元素,然后立即查询该工作的结果时,就会发生这种情况。结果是,浏览器必须先执行布局工作,然后才能执行任何其他操作,以便浏览器可以返回更新后的样式。有关避免强制回流的更多信息和技巧,请阅读避免大型、复杂的布局和布局抖动
  • requestAnimationFrame 回调中过多的或不必要的工作。 requestAnimationFrame() 回调在事件循环的渲染阶段运行,并且必须在可以呈现下一帧之前完成。如果您正在使用 requestAnimationFrame() 来执行不涉及用户界面更改的工作,请理解您可能会延迟下一帧。
  • ResizeObserver 回调。 此类回调在渲染之前运行,如果其中的工作开销很大,可能会延迟下一帧的呈现。与事件回调一样,延迟下一帧不需要的任何逻辑。

如果您无法重现慢速交互怎么办?

如果您的现场数据表明某个特定交互速度缓慢,但您无法在实验室中手动重现该问题怎么办?出现这种情况可能有一些原因,但一个重要的原因是您在测试交互时的环境取决于您的硬件和网络连接。您可能正在快速连接上使用快速设备,但这并不意味着您的用户也是如此。如果这适用于您,您可以尝试以下三件事之一

  1. 如果您有物理 Android 设备,请使用远程调试在您的主机上打开 Chrome DevTools 实例,并尝试在那里重现慢速交互。移动设备通常不如笔记本电脑或台式计算机快,因此在这些设备上可能更容易观察到慢速交互。
  2. 如果您没有物理设备,请在 Chrome DevTools 中启用 CPU 节流功能
  3. 可能是您在与页面交互之前等待页面加载,但您的用户不是这样。如果您在快速网络上,请通过启用网络节流来模拟较慢的网络条件,然后在页面绘制后立即与页面交互。您应该这样做,因为主线程通常在启动期间最繁忙,并且在该时间段内进行测试可能会揭示您的用户正在体验的内容。

排除 INP 故障是一个迭代过程

找出导致高交互延迟从而导致 INP 不佳的原因需要大量工作,但如果您可以确定原因,那么您就成功了一半。通过采用有条不紊的方法来排除 INP 不佳的故障,您可以可靠地确定导致问题的原因,并更快地找到正确的修复方法。回顾一下

  • 依靠现场数据查找慢速交互.
  • 在实验室中手动测试有问题的现场交互,以查看它们是否可重现。
  • 确定原因是由于长时间输入延迟、开销大的事件回调还是开销大的渲染工作。
  • 重复。

最后一点是最重要的。与您为提高页面性能所做的其他大多数工作一样,排除和改进 INP 故障是一个循环过程。当您修复一个慢速交互时,请继续下一个,并重复直到您开始看到结果。