性能不佳 - SVG 动画

3

我正在为一个客户创建一些动画,我一直在使用two.js,因为它具有SVG功能。不幸的是,我遇到了性能问题。

我在屏幕上绘制了100个圆形。每个圆形包含6个更小的圆形,共渲染了700个圆形。

这些圆形会根据鼠标在x轴上的移动而做出反应,并在y轴上缓慢地向下级联。

目前在Chrome中,它只运行在大约32FPS左右。在Firefox中几乎完全无法工作!

我还尝试过two.js的webgl渲染器,但虽然性能略有提高,但元素的外观就不如SVG好看了。

源代码在此处:https://github.com/ashmore11/verifyle/tree/develop

文件路径:src/coffee/elements/dots

如果需要更多信息,请让我知道。


SMIL或CSS动画通常比JavaScript动画具有更好的性能。 - Robert Longson
您的Dev链接指向源代码... - jonobr1
1个回答

13

你做的很漂亮!

嗯,为什么性能不如你所愿有许多因素。

  1. 可绘制区域的大小很重要(即:<svg /><canvas />元素)。面积越大,需要渲染的像素就越多。
  2. 添加到DOM中的元素数量。是的,有100个点,但每个点由许多元素组成。
  3. 这些元素中每个元素在任何给定帧上的更改量。
  4. 最后,元素更改的操作数量(即:opacityscaletranslation等)。

这些考虑因素在大多数计算机生成的图像中会影响实时渲染。基本目标是减少任何一个维度的负载,并查看是否足以提供您所需的性能。你需要有创意,但有一些选择。以下是我脑海中可以尝试加快速度的一些事情:

  • 减少图形数量可以使其运行更快^^
  • 对于像这样的Two.Types.canvas,它可能是最快的。
  • 不要移动每个点,而是将translation分成2或3组,并根据容器组移动它们。有点像前景和背景的视差效果。
  • 如果你坚持使用Two.Types.svg,尝试在任何给定帧上仅对少量点进行动画处理。这样,您就不必每帧遍历整个场景,每个点也不会每帧都进行动画处理。

这个伪代码大概长下面这样:

// ... some array : dots inferred ... //

var now = Date.now();
var index, length = 12;

two.bind('update', function() {
  for (var i = index; i < Math.min(index + 12, dots.length); i++) {
    var dot = dots[i];
    dot.scale = (Math.sin(now / 100) + 1) / 4 + 0.75;
  }
  index = (index + 12) % dots.length;
});
  • 如果这些都没有给你想要的实质性内容,我强烈建议将每个Dot转换为纹理,并直接通过canvas2d或使用WebGL和库来绘制这些纹理。 Three.js 将能够渲染成千上万个这样的粒子:http://threejs.org/examples/#webgl_particles_sprites 您必须重新考虑纹理本身的生成方式以及不透明度在线条之间的变化方式,当然它会像您在问题中描述的那样略有不同。位图与矢量图是不同的 >_<

希望这可以帮助到您!


3
非常感谢 @jonobr1 提供的详细答案。不幸的是,客户还在要求更多的点 :( 昨晚我把所有内容都移植到了 pixi.js 上,以利用 webgl 并提供画布回退功能,现在性能达到了我的期望水平。虽然如此,我真的很喜欢你的库,并且将来一定会百分之百地在我的个人项目中使用它。感谢你的辛勤工作。 - Ashmore11
4
当对SVG元素进行动画和转换时,也存在性能问题。它们会触发绘制操作,每次都会发生。请参阅:http://www.crmarsh.com/svg-performance(该文章来自2014年,自那以后没有改变。如果我有误,请纠正我。) - mahish

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