Chrome представляет собой слои композиций без запуска перерисовки

Во время отладки библиотеки холста, над которой я работаю, я столкнулся с тем, что chrome-devtools постоянно сообщают о "составных слоях" и "обновляет дерево слоев" для каждого анимационного кадра без перекраски или перемещения каких-либо объектов.

Пример:

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

Эти операции не зависят от времени (0.005-0.05 мс каждый кадр), но я хотел бы знать, почему это происходит.

Единственная идея, которая приходит мне на ум, заключается в том, что хром использует нечто похожее на:

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",... не запускаются одинаково?

Update:

  • Это происходит в Chrome 36/37 (Windows)
  • On Chromium 34 (Linux) отображает только составные слои
  • другие системы непроверенные

Edit1: Это происходит только при использовании requestAnimationFrame. setInterval показывает только таймер, как ожидалось.

Edit2: Полный исходный код примера: pastebin

Ответ 1

Из https://code.google.com/p/chromium/issues/detail?id=325419:

... даже если ничто не меняет выход пикселя на экран, для страницы может быть отменено полное отображаемое состояние например. загрязняя стиль документа. У Blink нет выбора, кроме как recalc-стиль, ретрансляция, краска и композит в этот момент. Иногда эти шаги могут быть ранними, когда ничего не изменилось, но это трудно знать наверняка.

См. также Архитектура потока композитора - похоже, что rAF запускает синхронизацию уровня дерева между двумя потоками компоновщика.