了解Chrome Dev Tools时间表

时间:2017-01-15 19:48:19

标签: google-chrome-devtools jank

我试图了解为什么Chrome Dev Tools报告了多个长帧。

enter image description here

火焰图表中的第一行(调用堆栈的顶部)主要是Timer Fired个事件,由jQuery.Deferred()执行一堆$(function(){ });就绪函数触发。

如果我深入研究jQuery源代码并将setTimeout替换为requestAnimationFrame,火焰图表的变化不大,我仍然会在一个帧内触发许多rAF(如dev所报告的那样)制作长帧的工具。我曾期望做下面的伪代码:

window.requestAnimationFrame(function() {
    // do stuff
});

window.requestAnimationFrame(function() {
    // do more stuff
});

在两个不同的动画帧上执行。情况不是这样吗?

正在执行的所有JS都是必要的,但我应该怎样执行它作为"微任务" (正如setTimeoutrAF似乎无法实现此目的时所暗示的https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution)。

更新

下面是其中一个看似没有任何回流(强迫或其他)的长帧的放大镜头。为什么这里的所有rAF回调都在一帧中执行?

enter image description here

由于

1 个答案:

答案 0 :(得分:4)

长帧通常由强制同步布局引起,这是您(无意中)强制布局操作提前发生的时间。

当您写入DOM时,需要重新布局布局,因为它已被写操作无效。这通常发生在下一帧。但是,如果您尝试从DOM读取,则布局会在当前帧中提前发生,以确保返回正确的值。当强制布局发生时,它会导致长帧,导致抖动。

为防止这种情况发生,您应该只在requestAnimationFrame功能中执行写操作。读取操作应该在此之外完成,以避免浏览器进行早期布局。

Diagnose Forced Synchronous Layouts是一篇很好解释的文章,有一个简单的示例演示,用于检测DevTools中的强制重排,以及如何解决它。

也许值得查看FastDom,这是一个用于批量读写的库。它基本上是一个排队系统,并且更具可扩展性。

其他来源: Paul Irish提供的What forces layout / reflow包含一系列强制布局/重排的属性和方法。

更新:对于多个requestAnimationFrame调用将在不同的帧上执行回调的假设,情况并非如此。当您有连续调用时,浏览器会将回调添加到动画回调的文档列表中。当浏览器运行下一帧时,它会遍历文档列表并按照添加的顺序执行每个回调。

有关更多实施详细信息,请参阅HTML规范中的Animation Frames

这意味着您应该避免使用连续调用,特别是在回调函数执行时间合并超出帧预算的情况下。我认为这可以解释不是由回流引起的长帧。