为什么我在每个 requestAnimationFrame 处理程序之后都有 "Update Layer Tree" 和 "Composite Layer" 任务?

Why I have "Update Layer Tree" and "Composite Layer" tasks after each requestAnimationFrame handler?

我正在尝试编写高性能 60 - 140fps 渲染代码,但我注意到在每次 requestAnimationFrame Chrome 调用 "Update Layer Tree" 和 "Composite Layer" 总结的任务比我的渲染函数花费更多的脚本时间。我不明白为什么会这样?我不更新任何 css 或调整元素大小,因此我认为我的代码不需要一些额外的重新计算。

你会发现在这个例子中发生了同样的事情:https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations

Why I have “Update Layer Tree” and “Composite Layer” tasks after each requestAnimationFrame handler?

因为浏览器需要完成这些任务。 "Update Layer Tree" 可能什么都不做。如果你没有改变 HTML 和 CSS 并且没有 CSS 动画 运行 代码可能很简单

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

"Composite Layers" 是您的 WebGL 显示在屏幕上的方式。当 GPU 加速时,浏览器将网页元素的各个部分存储为纹理。 WebGL canvas 有自己的纹理。然后它将所有这些纹理绘制到浏览器 window。除非什么都没有改变,你没有改变任何 HTML 也没有 CSS 也没有画到你的 canvas 没有 CSS 动画没有视频没有 gifs)那么总会有一个 "Composite Layers"步骤。和上面一样,它可能被实现为

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>

我看到同样的两个进程存在,但我也看到我是否影响 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>

它们上升表明它们已按上述方式实现,检查它们是否有任何工作要做。我在 a fairly complicated page 上进行了测试,虽然它没有更新任何 html,但有数百个元素和几个带有实时代码编辑器的 iframe(6319 个元素),我仍然认为这 2 个任务没有花费那么长时间,每个低于 0.40 毫秒。