Почему у меня есть задачи «Обновить дерево слоев» и «Составной слой» после каждого обработчика requestAnimationFrame? - PullRequest
1 голос
/ 10 апреля 2020

Я пытаюсь написать высокопроизводительный код рендеринга 60 - 140 кадров в секунду, но заметил, что после каждого requestAnimationFrame Chrome вызывает задачи «Обновить дерево слоев» и «Составной слой», для суммирования которых требуется больше времени. время сценариев, чем моя функция рендеринга. Я не понимаю, почему это происходит? Я не обновляю css и не изменяю размеры элементов, поэтому я не думаю, что мой код требует дополнительных перерасчетов.

dev-tools screenshot

Вы можете найти что то же самое происходит в этом примере: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations

1 Ответ

1 голос
/ 10 апреля 2020

Почему у меня есть задачи «Обновить дерево слоев» и «Составной слой» после каждого обработчика requestAnimationFrame?

Поскольку браузер должен выполнять эти задачи. «Обновить дерево слоев» может ничего не делать. Если вы изменили не HTML и CSS, а анимации CSS не запущены, код может быть простым, как

function UpdateLayerTree() {
  performance.start("Update Layer Tree");
  if (layerTreeNeedsUpdating) {
     ... update tree ...
  }
  performance.end();
}

«Составные слои» - это то, как ваш WebGL попадает на экран. Браузер при ускорении графического процессора сохраняет различные части элементов веб-страницы в виде текстур. У холста WebGL есть своя собственная текстура. Затем он выводит все эти текстуры в окно браузера. Если ничего не изменилось, вы не изменили ни HTML, ни CSS, ни нарисованные на холсте, ни CSS анимации, ни видео, ни картинки), тогда всегда будет шаг "Композитные слои". И как выше, это может быть реализовано как

function CompositeLayers() {
  performance.start("Composite Layers");
  if (needToRedrawBecauseContentChanged) {
     ... composite layers ...
  }
  performance.end();
}

Проверка, если напишите код, подобный этому

const gl = document.querySelector('canvas').getContext('webgl');

function render(time) {
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
<canvas></canvas>

Я вижу, что существуют те же самые два процесса, но я также вижу, влияю ли я на холст

const gl = document.querySelector('canvas').getContext('webgl');

function render(time) {
  gl.clearColor(time / 100 % 1, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
<canvas></canvas>

Они go вверх, что говорит о том, что они реализованы, как указано выше, проверяя, есть ли у них работа. Я протестировал на довольно сложную страницу , которая не обновляет никаких html, но содержит сотни элементов и несколько iframes с редакторами живого кода (6319 элементов), и я все еще видел, что эти 2 задачи не выполняются все это, под 0,40 мс каждый.

...