了解 Chrome 开发工具时间表
Understanding Chrome Dev Tools timeline
我想了解为什么 Chrome 开发工具报告了几个长帧。
火焰图中的第一行(调用堆栈的顶部)主要是 Timer Fired
事件,由 jQuery.Deferred()
执行一堆 $(function(){ });
就绪函数触发。
如果我深入研究 jQuery 来源并将他们对 setTimeout
的使用替换为 requestAnimationFrame
火焰图变化不大,我仍然可以看到许多 rAFs 在其中燃烧单帧(由开发工具报告)制作长帧。我原以为会执行以下伪代码:
window.requestAnimationFrame(function() {
// do stuff
});
window.requestAnimationFrame(function() {
// do more stuff
});
在两个不同的动画帧上执行。不是这样吗?
所有正在执行的 JS 都是必需的,但是当 setTimeout
时,我应该怎么做才能将其执行为 "micro tasks"(如提示,但未在此处解释 https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution) rAF
似乎没有做到这一点。
更新
这是其中一个似乎没有任何回流(强制或其他方式)的长帧的放大镜头。为什么这里所有的rAF回调都是一帧执行的?
长帧通常是由强制同步布局引起的,即您(无意中)强制布局操作提前发生。
当您写入DOM时,布局需要重排,因为它已被写入操作无效。这通常发生在下一帧。但是,如果您尝试从 DOM 读取,布局会在当前帧中提前发生,以确保返回正确的值。当发生强制布局时,会导致长帧,导致卡顿。
为防止这种情况发生,您应该只在 requestAnimationFrame
函数内执行写操作。读取操作应该在此之外进行,以避免浏览器进行早期布局。
Diagnose Forced Synchronous Layouts 是一篇解释得很好的文章,并且有一个简单的示例演示,用于检测 DevTools 中的强制回流,以及如何解决它。
可能还值得一试 FastDom,这是一个用于批处理读写的库。它基本上是一个排队系统,并且更具可扩展性。
其他来源:
What forces layout / reflow,作者 Paul Irish,包含将强制 layout/reflow.
的属性和方法的完整列表
更新:至于假设多个requestAnimationFrame
调用会在不同的帧上执行回调,事实并非如此。当您连续调用时,浏览器会将回调添加到动画回调的文档列表中。当浏览器转到 运行 下一帧时,它遍历文档列表并按照添加的顺序执行每个回调。
有关更多实施细节,请参阅 HTML 规范中的 Animation Frames。
这意味着您应该避免使用连续调用,尤其是在回调函数执行时间加起来超过您的帧预算的情况下。我认为这可以解释不是由回流引起的长帧。
我想了解为什么 Chrome 开发工具报告了几个长帧。
火焰图中的第一行(调用堆栈的顶部)主要是 Timer Fired
事件,由 jQuery.Deferred()
执行一堆 $(function(){ });
就绪函数触发。
如果我深入研究 jQuery 来源并将他们对 setTimeout
的使用替换为 requestAnimationFrame
火焰图变化不大,我仍然可以看到许多 rAFs 在其中燃烧单帧(由开发工具报告)制作长帧。我原以为会执行以下伪代码:
window.requestAnimationFrame(function() {
// do stuff
});
window.requestAnimationFrame(function() {
// do more stuff
});
在两个不同的动画帧上执行。不是这样吗?
所有正在执行的 JS 都是必需的,但是当 setTimeout
时,我应该怎么做才能将其执行为 "micro tasks"(如提示,但未在此处解释 https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution) rAF
似乎没有做到这一点。
更新
这是其中一个似乎没有任何回流(强制或其他方式)的长帧的放大镜头。为什么这里所有的rAF回调都是一帧执行的?
长帧通常是由强制同步布局引起的,即您(无意中)强制布局操作提前发生。
当您写入DOM时,布局需要重排,因为它已被写入操作无效。这通常发生在下一帧。但是,如果您尝试从 DOM 读取,布局会在当前帧中提前发生,以确保返回正确的值。当发生强制布局时,会导致长帧,导致卡顿。
为防止这种情况发生,您应该只在 requestAnimationFrame
函数内执行写操作。读取操作应该在此之外进行,以避免浏览器进行早期布局。
Diagnose Forced Synchronous Layouts 是一篇解释得很好的文章,并且有一个简单的示例演示,用于检测 DevTools 中的强制回流,以及如何解决它。
可能还值得一试 FastDom,这是一个用于批处理读写的库。它基本上是一个排队系统,并且更具可扩展性。
其他来源: What forces layout / reflow,作者 Paul Irish,包含将强制 layout/reflow.
的属性和方法的完整列表更新:至于假设多个requestAnimationFrame
调用会在不同的帧上执行回调,事实并非如此。当您连续调用时,浏览器会将回调添加到动画回调的文档列表中。当浏览器转到 运行 下一帧时,它遍历文档列表并按照添加的顺序执行每个回调。
有关更多实施细节,请参阅 HTML 规范中的 Animation Frames。
这意味着您应该避免使用连续调用,尤其是在回调函数执行时间加起来超过您的帧预算的情况下。我认为这可以解释不是由回流引起的长帧。