Chrome在合成图层时没有触发重绘。

11

在调试我正在开发的画布库时,我遇到了一个问题,Chrome 开发者工具会在每个 animationframe 中报告“合成层”和“更新层树”,但没有重新绘制或移动任何对象。

例如:

var x = 0;
( function tick( ) {
    window.requestAnimationFrame(tick);
    x++;
}( ) )

这些操作不耗时(每帧 0.005-0.05 毫秒),但我想知道为什么会发生这种情况。

我能想到的唯一想法是,Chrome 使用类似于:

console.time( "composite layers" );
// do compositing    
for( var i = 0; i < compositedLayers.length; ++i ) {
   // not triggered since compositedLayers.length = 0
   // but takes some time to be checked
   compositedLayers[i].composite();
}
console.timeEnd( "composite layers" );

如果是这样的话,为什么“Paint”、“Recalculate Style”、“Layout”等操作不会以同样的方式触发?

更新:

  • 此问题发生在Chrome 36/37(Windows)中
  • 在Chromium 34(Linux)中,它只显示复合图层
  • 其他系统未经测试

Edit1:只有使用requestAnimationFrame时才会出现这种情况。与预期相同,setInterval只显示计时器已启动。

Edit2:示例的完整源代码:pastebin


你尝试过使用 $ trigger(resize) 吗? - STEEL
看编辑链接,那是完整的源代码。没有 jQuery,没有其他库,没有 DOM 操作,没有画布,什么都没有。 - bbuecherl
但是你没有对DOM做任何操作,那么它为什么要这样做呢?编辑:哦,抱歉我没读对,但既然你请求了一个animationframe,它应该这样做才对吧? - EaterOfCode
这正是我的问题... rAF 不应该像 setInterval 一样工作吗? - bbuecherl
我的意思是你能触发调整大小事件,然后看它是否重新绘制。 - STEEL
它确实会这样做,但问题是Chrome会重新绘制,而不做任何事情。 - bbuecherl
1个回答

6

来自https://code.google.com/p/chromium/issues/detail?id=325419

即使屏幕上的像素输出没有发生任何变化,页面也可能通过脏化文档的样式来使整个渲染状态失效。在这种情况下,Blink别无选择,只能重新计算样式、重新布局、绘制和合成。有时候,当没有实际发生变化时,这些步骤可以提前退出,但很难确定。

另请参见Compositor线程架构 - 看起来rAF会触发两个合成器线程之间的层树同步。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接