即使帧的任务是 8ms 也没有达到 60fps

Posted

技术标签:

【中文标题】即使帧的任务是 8ms 也没有达到 60fps【英文标题】:60fps not met even though frame's tasks are 8ms 【发布时间】:2016-04-03 07:23:33 【问题描述】:

我正在使用 Google 的开发者工具时间线。我有一个动画:

http://output.jsbin.com/yecudotija/1

&我机器上的时间线:

https://www.dropbox.com/s/0opclvbvb82ff8f/TimelineRawData-20151229T130820.json?dl=0

(我使用的是 Chrome 47),尽管所有任务所需的时间是 8 毫秒,但整个帧是 26 毫秒 - 所以不能满足 60 fps,我有一个垃圾:

知道这是为什么吗?

【问题讨论】:

如果没有演示,我看不出我们如何可能回答这个问题。 好了,我已经更新了问题。但是我认为它更多地与帧的渲染方式有关,截图就足够了。 【参考方案1】:

你有 jank,因为你有 一个 巨大的层被重绘每一帧。它几乎有 12000 像素长。你需要找到一种方法来减少这种情况。

要解决这个问题,请打开“绘制”配置文件并关闭其余部分。然后只需运行 2-3 秒的快速配置文件。框架太大了,计算数据需要一点时间。

一旦出现,单击框架并检查它的图层面板。这显示了巨大的框架,可以很好地指示绘画发生的位置。

另一个缺点是,你有大量的.box div,所有这些都是will-change。这正是 will-change 的用途。并非所有这些 div 都在变化。所以你给引擎带来了一堆噪音,它做的工作比需要的多得多。绝对具体说明将要更改的内容和用途。你也告诉它你正在用一个变换来改变它,这永远不会发生。因此,如果引擎在产生所有噪音的情况下做任何事情,它根本没有帮助。

还注意到您的更改,背景颜色导致repaint and re-composition。您应该避免修改它,而是寻找替代方法(例如修改元素的不透明度或两个元素之间的不透明度)以获得相同的结果。

tl;博士

1) 避免大层。它们非常昂贵。

2) 避免大量不需要的层(比如所有这些.box div。)

3) 仅对实际会改变的元素使用will-change

4) 提供改变的正确事物。所以引擎会尽力而为。

5) 尽量避免修改背景颜色。

【讨论】:

这只是其中一个在线课程的练习代码。非常感谢您的出色回答! 一个问题:为什么在我的时间线(例如 26 毫秒帧)中大部分时间是“空闲”(只有 8 毫秒是真正的工作)?我的意思是它没有暗示任何一项或其他操作很耗时。 我也玩过不透明度。这里有两个版本(背景颜色和不透明度变化的动画)。查看时间线时,我看不出有什么区别,触发器布局和绘制:output.jsbin.com/tixaloq/12 & output.jsbin.com/tixaloq/14。我还是做错了吗? 您不只是附加不透明度更改。您仍然会从元素的背景颜色更改中重新绘制。您实际上会堆叠两个元素。白色之上的灰色。然后将灰色不透明度设置为0并将其更改为1。删除不透明度部分,这应该没问题。它在 16 毫秒范围内。 啊,我误读了设置(试图通过元素面板进行设置,而一切都在进行中。)是的,没关系。你在性能边界。 This jsbin 进行了更多优化。在每个循环中做更少的逻辑,将改变盒子。除此之外,你不会变得更好。据我所知,这不会触发布局,只是重新计算样式(来自切换)然后重新绘制(来自不透明度更改。)

以上是关于即使帧的任务是 8ms 也没有达到 60fps的主要内容,如果未能解决你的问题,请参考以下文章

React Fiber reconciler

利用好浏览器的空闲时间 --- requestIdleCallback

Android 渲染优化

iOS之性能优化·列表异步绘制

auto.js界面假死

为啥即使源代码没有变化,Gradle 的“构建”任务也不是最新的?