拉斐尔:用简单的无限动画逐渐减速

时间:2022-11-20 18:27:14

This question is similar in spirit to this other question, asked two years ago: Why does Raphael's framerate slow down on this code?

这个问题在精神上与两年前提出的另一个问题相似:为什么拉斐尔的framerate会减慢这个代码?

I'm using Raphael 2.1.0 in Chromium 25 in the following way:

我使用的是Raphael 2.1.0在Chromium 25中的方式如下:

<html>
<head>
  <title>Drawfun</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>
  <script src="raphael.js"></script>
  <script>
    var paper = Raphael(10, 50, 320, 200);
    var anim = Raphael.animation({transform: "R360"}, 500).repeat(Infinity);

    var rect = paper.rect(50, 40, 10, 20);
    rect.attr("fill", "#f00");
    rect.attr("stroke", "#fff");
    rect.animate(anim);
  </script>
</body> 
</html> 

Initially, the rectangle spins smoothly, as one would expect. After a minute or two, the rotation is running at ~15 FPS. After five or eight minutes, the animation is running at ~5 FPS.

最初,矩形像人们预期的那样,平滑地旋转。一两分钟后,旋转速度为~15英尺。五到八分钟后,动画以大约五英尺的速度运行。

Chrome CPU profiles indicate that as the animation becomes more choppy, the script is spending less and less time in (program) and more and more time in repush and eve.listeners.

Chrome CPU配置文件表明,随着动画变得越来越不稳定,脚本在(程序)中花费的时间越来越少,在repush和eve.listener中花费的时间越来越多。

The Chrome task manager doesn't indicate that there's a memory leak, either in the JS memory pool or in Chrome's, but does reveal that the page consumes more and more CPU over time.

Chrome任务管理器并不表示存在内存泄漏,无论是在JS内存池中还是在Chrome中,但它的确显示了页面随着时间的推移会消耗越来越多的CPU。

When running that page in a recent version of Firefox, the animation becomes choppy much, much more quickly. These results have been verified on Linux and Windows, so it's not an OS issue :).

当在最新版本的Firefox中运行该页面时,动画会变得非常、非常快。这些结果已经在Linux和Windows上得到了验证,所以这不是一个OS问题:)。

Does anyone have any insight into what might be wrong with either my code or Raphael's internals?

有人知道我的代码或拉斐尔的内部代码有什么问题吗?

1 个解决方案

#1


2  

Okay, I know this isn't exactly the answer that anyone wants to hear (and is a debatable cop-out), but from the look of Raphael, and the reading of the comments above, I can't help but think that this is a garbage collection issue, and is the reason for the varying results across everyone's browsers. From a quick glance over the Raphael source, it looks like quite a bit of vars are declared or implemented in the process of animating a frame, on a per frame basis. I know for a fact that at least in Chrome's V8 engine, each var is declared in a trackable method and put on the heap, the delay in the framerate reduction only further indicates that the garbage collector is kicking into high mode to free up chunks of declared vars that are no longer in use. I would bet good money that if you were to move a lot of the declarations in the Raphael script into a higher scope (maybe even global, gasp~!), specifically during the animation sequences you will find a very much improved frame-rate over the course of the script.

好吧,我知道这并不是答案,任何人都想听(而且是一个有争议的借口),但从拉斐尔的外观,和阅读上面的评论,我不禁认为这是一个垃圾收集的问题,并在每个人的浏览器中的不同结果的原因。快速浏览一下Raphael源,似乎有相当多的vars是在每个帧的基础上对一个帧进行动画的过程中声明或实现的。我知道一个事实,至少在Chrome的V8引擎,每个var声明在一个可跟踪的方法,把堆,只减少延迟在帧速率进一步表明,垃圾收集器是踢到高模式释放大量var宣布不再使用。我敢打赌,如果您将Raphael脚本中的许多声明移动到更高的范围(甚至可能是全局的,gasp~!

I ran into this problem on a custom implementation of an adaptation to webgl, basically i was making webgl commands work without webgl enabled. The rasterizer of the pipeline I built had a very similiar problem as this, basically it would draw the frames starting at 68fps, but by the end of the test, would be down to 13fps or lower, and at 98% processor use. It wasn't until I cleaned up every single declaration that created new memory allocations out of the pipeline scope (and did a few more well researched speed up tricks having to do with variable lookups) that I was finally able to keep up and produce a well written rasterizer that could pump about 3-5MB/s of pixels to the screen at a time while keeping a 50-60fps rate.

我在一个自定义的webgl的自适应实现上遇到了这个问题,基本上是我让webgl命令在没有webgl的情况下工作。我构建的管道的光栅化器有一个非常类似的问题,基本上它会绘制从68fps开始的帧,但是在测试结束时,将会降到13fps或更低,并且在98%的处理器上使用。直到我清理每一个宣言,创造了新的内存分配管道的范围(和做了一些研究加速技巧与变量查找),我终于能够保持和生产井写光栅化程序可以泵关于3-5MB / s的像素在屏幕上同时保持50-60fps率。

Again, not sure if this is the answer you want or need, but I think it is the correct one. :( Sorry I couldn't help any more than that. Good luck :)

再说一遍,我不确定这是否是你想要或需要的答案,但我认为这是正确的答案。)对不起,我帮不了你什么忙。祝你好运:)

#1


2  

Okay, I know this isn't exactly the answer that anyone wants to hear (and is a debatable cop-out), but from the look of Raphael, and the reading of the comments above, I can't help but think that this is a garbage collection issue, and is the reason for the varying results across everyone's browsers. From a quick glance over the Raphael source, it looks like quite a bit of vars are declared or implemented in the process of animating a frame, on a per frame basis. I know for a fact that at least in Chrome's V8 engine, each var is declared in a trackable method and put on the heap, the delay in the framerate reduction only further indicates that the garbage collector is kicking into high mode to free up chunks of declared vars that are no longer in use. I would bet good money that if you were to move a lot of the declarations in the Raphael script into a higher scope (maybe even global, gasp~!), specifically during the animation sequences you will find a very much improved frame-rate over the course of the script.

好吧,我知道这并不是答案,任何人都想听(而且是一个有争议的借口),但从拉斐尔的外观,和阅读上面的评论,我不禁认为这是一个垃圾收集的问题,并在每个人的浏览器中的不同结果的原因。快速浏览一下Raphael源,似乎有相当多的vars是在每个帧的基础上对一个帧进行动画的过程中声明或实现的。我知道一个事实,至少在Chrome的V8引擎,每个var声明在一个可跟踪的方法,把堆,只减少延迟在帧速率进一步表明,垃圾收集器是踢到高模式释放大量var宣布不再使用。我敢打赌,如果您将Raphael脚本中的许多声明移动到更高的范围(甚至可能是全局的,gasp~!

I ran into this problem on a custom implementation of an adaptation to webgl, basically i was making webgl commands work without webgl enabled. The rasterizer of the pipeline I built had a very similiar problem as this, basically it would draw the frames starting at 68fps, but by the end of the test, would be down to 13fps or lower, and at 98% processor use. It wasn't until I cleaned up every single declaration that created new memory allocations out of the pipeline scope (and did a few more well researched speed up tricks having to do with variable lookups) that I was finally able to keep up and produce a well written rasterizer that could pump about 3-5MB/s of pixels to the screen at a time while keeping a 50-60fps rate.

我在一个自定义的webgl的自适应实现上遇到了这个问题,基本上是我让webgl命令在没有webgl的情况下工作。我构建的管道的光栅化器有一个非常类似的问题,基本上它会绘制从68fps开始的帧,但是在测试结束时,将会降到13fps或更低,并且在98%的处理器上使用。直到我清理每一个宣言,创造了新的内存分配管道的范围(和做了一些研究加速技巧与变量查找),我终于能够保持和生产井写光栅化程序可以泵关于3-5MB / s的像素在屏幕上同时保持50-60fps率。

Again, not sure if this is the answer you want or need, but I think it is the correct one. :( Sorry I couldn't help any more than that. Good luck :)

再说一遍,我不确定这是否是你想要或需要的答案,但我认为这是正确的答案。)对不起,我帮不了你什么忙。祝你好运:)