在 Firefox 与 Chrome 中使用 css 变换旋转的性能问题

问题描述 投票:0回答:2

我正在尝试查明原因,如果可能的话,找到解决方案或解决方法来解决我在 Firefox 中更新大约 200 个 span 元素的转换时遇到的性能问题。 在 Chrome 中,我能够实现流畅的 60fps,但 Firefox 中的同一示例存在巨大的性能问题,这些问题似乎是在更新元素的

rotate
转换时引入的。

我在这里重现了这个问题: https://codepen.io/Epz-the-bold/pen/BaGvGLx

我已经测试过,通过删除

rotate
转换部分,Firefox 可以与 Chrome 的 FPS 保持在约 55-60fps 的水平。

有人对导致此问题的原因和/或可能的解决方案有任何指示吗?

澄清为什么我不使用 CSS 转换(这在 FF 中可以正常工作),而是更新每个帧上的转换:在我的原始代码中。我正在运行物理模拟来更新每个跨度的位置和旋转,因此这些应该由物理引擎管理以保持 DOM 和模拟之间的一致性。

javascript css performance firefox css-transforms
2个回答
0
投票

使用transform:rotateZ()而不是rotate():不要使用rotate()函数,而是尝试使用带有transform属性的rotateZ()。 rotateZ() 是一个 2D 变换,在某些情况下可能有更好的性能。

function update() {
  spans.forEach(span => {
    span.x += span.velocity.x;
    span.y += span.velocity.y;
    span.rotation += span.velocity.x * 0.01;

    // Update only the translate transform and use rotateZ()
    span.el.style.transform = `translate3d(${span.x}px, ${span.y}px, 0) rotateZ(${span.rotation}rad)`;

    const bb = span.el.getBoundingClientRect();
    // ... Rest of the code ...
  });

  requestAnimationFrame(update);
}

0
投票

解决方案

transform-style: preserve-3d;
添加到跨度完全解决了问题,我现在在 Firefox 和 Chrome 中看到一致的 fps。我的猜测是,这会迫使 FF 在
translate3d
rotateZ
不起作用的情况下使用硬件加速。

缓解措施

在转换属性中添加一个短过渡似乎有助于缓解 Firefox 中的这个问题,根据我的测试,过渡持续时间应该高于平均帧时间,否则会导致更多卡顿:

transition: transform 100ms linear;
© www.soinside.com 2019 - 2024. All rights reserved.