PerformanceLongAnimationFrameTiming: blockingDuration 属性

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

实验性: 这是一项实验性技术
在生产中使用此技术之前,请仔细检查浏览器兼容性表格

PerformanceLongAnimationFrameTiming 接口的只读属性 blockingDuration 返回一个 DOMHighResTimeStamp,指示主线程因响应高优先级任务(例如用户输入)而被阻塞的总时长(以毫秒为单位)。

描述

blockingDuration 的计算方法是:取 LoAF(长帧动画时序)中 duration 大于 50ms 的所有 长任务,从每个任务中减去 50ms,将渲染时间加到最长任务时间上,然后将结果相加。让我们通过一个例子来阐明这一点。

假设一个 JavaScript 文件总共需要 145 毫秒来处理。在脚本的第一个主要部分处理完 65 毫秒后,我们可以考虑将剩余脚本的执行拆分成第二个任务,第二个任务需要 80 毫秒来执行。与将整个脚本作为一个任务执行相比,这样拆分执行更有利,因为它让浏览器有机会在任务之间处理用户交互。这种方法被称为让步(yielding)。例如,您可以在脚本的第一个主要部分执行完毕后插入一个 setTimeout() 来让步。

这里有三种脚本可能的处理方式可供考虑:

  1. 如果在前 65 毫秒后让步,浏览器可以在运行剩余脚本之前决定渲染一帧。
  2. 或者,浏览器可以先运行剩余的脚本,然后再渲染帧。
  3. 我们也可以选择让步,让浏览器将整个脚本作为一个任务来处理。

注意: 浏览器通常会尝试优先处理重要任务,例如用户交互和渲染新帧,而不是它可能排队的次要任务。浏览器会尝试每 16 毫秒渲染一帧。

我们之前提到脚本的总处理时间为 145 毫秒。假设 UI 更新的渲染时间为 10 毫秒,则三种情况下 LoAF 的时序如下:

选项 duration (LoAF 1) blockingDuration (LoAF1) duration (LoAF2) blockingDuration (LoAF2)
1 65毫秒 15毫秒 (65 - 50) 80毫秒 40毫秒 (80 + 10 - 50)
2 145毫秒 (65 + 80) 55毫秒 ((65 - 50) + (80 + 10 - 50)) 不适用* 不适用*
3 145毫秒 (65 + 80) 105毫秒 ((65 + 80) + 10 - 50) 不适用* 不适用*

* 在选项 2 和 3 中,只有一个 LoAF。

请注意,前两种情况下的总 blockingDuration 相同(55 毫秒)—— 无论哪种情况,浏览器都决定以不同的方式拆分工作。

然而,选项 3 的 blockingDuration 要长得多,因为浏览器完全被阻塞,根本无法中断长任务。这凸显了优化长任务通过让步的重要性——无论浏览器如何决定处理任务,阻塞持续时间仍将比不让步时要短。

durationblockingDuration 之间差异的 LoAF 可以总结如下:

  • duration 是 LoAF 总响应时间的度量,它有助于理解帧的布局、绘制等是否花费了很长时间。
  • blockingDuration 是 LoAF 阻塞主线程响应高优先级任务(如用户交互)的总时长的度量,这可能导致 UI 感觉 卡顿。换句话说,它是 LoAF 对响应能力影响的度量。

每个任务的 blockingDuration 计算为 duration - 50ms 的原因是,响应延迟超过 50 毫秒后用户就能感知到。这个阈值是用户开始注意到迟钝的时候;因此,为了确定卡顿的严重程度,测量超过 50 毫秒的部分非常重要。有关更多详细信息,请参阅 总阻塞时间 (TBT)

一个 DOMHighResTimeStamp

示例

有关 Long Animation Frames API 的示例,请参阅 长动画帧计时

规范

规范
Long Animation Frames API
# dom-performancelonganimationframetiming-blockingduration

浏览器兼容性

另见