PerformanceLongAnimationFrameTiming: blockingDuration 属性
PerformanceLongAnimationFrameTiming 接口的只读属性 blockingDuration 返回一个 DOMHighResTimeStamp,指示主线程因响应高优先级任务(例如用户输入)而被阻塞的总时长(以毫秒为单位)。
描述
blockingDuration 的计算方法是:取 LoAF(长帧动画时序)中 duration 大于 50ms 的所有 长任务,从每个任务中减去 50ms,将渲染时间加到最长任务时间上,然后将结果相加。让我们通过一个例子来阐明这一点。
假设一个 JavaScript 文件总共需要 145 毫秒来处理。在脚本的第一个主要部分处理完 65 毫秒后,我们可以考虑将剩余脚本的执行拆分成第二个任务,第二个任务需要 80 毫秒来执行。与将整个脚本作为一个任务执行相比,这样拆分执行更有利,因为它让浏览器有机会在任务之间处理用户交互。这种方法被称为让步(yielding)。例如,您可以在脚本的第一个主要部分执行完毕后插入一个 setTimeout() 来让步。
这里有三种脚本可能的处理方式可供考虑:
- 如果在前 65 毫秒后让步,浏览器可以在运行剩余脚本之前决定渲染一帧。
- 或者,浏览器可以先运行剩余的脚本,然后再渲染帧。
- 我们也可以选择不让步,让浏览器将整个脚本作为一个任务来处理。
注意: 浏览器通常会尝试优先处理重要任务,例如用户交互和渲染新帧,而不是它可能排队的次要任务。浏览器会尝试每 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 要长得多,因为浏览器完全被阻塞,根本无法中断长任务。这凸显了优化长任务通过让步的重要性——无论浏览器如何决定处理任务,阻塞持续时间仍将比不让步时要短。
duration 和 blockingDuration 之间差异的 LoAF 可以总结如下:
duration是 LoAF 总响应时间的度量,它有助于理解帧的布局、绘制等是否花费了很长时间。blockingDuration是 LoAF 阻塞主线程响应高优先级任务(如用户交互)的总时长的度量,这可能导致 UI 感觉 卡顿。换句话说,它是 LoAF 对响应能力影响的度量。
每个任务的 blockingDuration 计算为 duration - 50ms 的原因是,响应延迟超过 50 毫秒后用户就能感知到。这个阈值是用户开始注意到迟钝的时候;因此,为了确定卡顿的严重程度,测量超过 50 毫秒的部分非常重要。有关更多详细信息,请参阅 总阻塞时间 (TBT)。
值
示例
有关 Long Animation Frames API 的示例,请参阅 长动画帧计时。
规范
| 规范 |
|---|
| Long Animation Frames API # dom-performancelonganimationframetiming-blockingduration |
浏览器兼容性
加载中…
另见
- 长动画帧计时
PerformanceScriptTiming- 优化长任务 - web.dev (2024)