Firefox 如果画布大于255x220,为什么FPS会下降?

Firefox 如果画布大于255x220,为什么FPS会下降?,firefox,html5-canvas,Firefox,Html5 Canvas,我在HTML5画布上发现了一个wierd现象。我得到的帧速率比预期的要低,但只有在Firefox中,而且只有一台计算机上(但不是在我测试的另一台计算机上)。wierd的问题是,如果我将画布大小减少到255x250或更小,Firefox的性能与其他浏览器类似。如果我再增加一个像素的宽度,FPS会迅速下降到三分之一 我制作了一个jsPerf来演示这个问题: (确保屏幕上有灰色矩形。如果没有,我会让测试失败,因为我发现如果你不小心滚动,它会改变结果。) 这四个测试用例与大多数系统上的大多数浏览器非常相

我在HTML5画布上发现了一个wierd现象。我得到的帧速率比预期的要低,但只有在Firefox中,而且只有一台计算机上(但不是在我测试的另一台计算机上)。wierd的问题是,如果我将画布大小减少到255x250或更小,Firefox的性能与其他浏览器类似。如果我再增加一个像素的宽度,FPS会迅速下降到三分之一

我制作了一个jsPerf来演示这个问题: (确保屏幕上有灰色矩形。如果没有,我会让测试失败,因为我发现如果你不小心滚动,它会改变结果。)

这四个测试用例与大多数系统上的大多数浏览器非常相似,但在这台装有Firefox 17的PC上,我看到了以下内容:

这台PC运行的是旧版Red Hat Linux,我猜它可能没有硬件加速支持(从操作系统方面)

那么,这可能是什么原因呢?我可以在代码中做些什么来规避这个问题吗?(例如,我一直在考虑使用几张小画布,而不是一张大画布。)


编辑: 这是一个独立的html文件,以及。唯一的区别是画布的宽度,251比250。(您可以注释掉微调器动画,这只是为了使问题可见。请原谅FPS计时器的准确性,它的实现非常简单。)


250px版本的速度约为60 FPS,事实上它似乎有上限。您可以增加
numIterations
变量,使框架函数绘制多个平铺。我可以得到高达numIterations=100,或120000瓦片/秒,同时仍然有一个像样的帧率。然而,251px版本甚至为numIterations=1提供了低于20的帧速率,或低于1000瓦片/秒。

这是有意义的,因为绘制画布和清除画布是昂贵的方法;如果您有一个较小的画布,并在每个动画步骤上调用
clearRect
,那么它将比运行完全相同代码的较大画布性能更好。最好的办法是优化绘制方法,只清除每个帧的变化。一旦你这样做了,你会发现一个性能提升;将有助于您提高性能的其他方面


我也在开发canvas,发现基于WebKit的浏览器在大多数情况下处理canvas操作的速度都比Gecko快。

我确实看到了类似的行为。我相信这是当你越过65776像素的障碍->不是65536,你会期待

我还不知道为什么会出现这种情况,但可能是浏览器内部存在某种内部数据结构或数据类型问题(可能是使用哈希,需要在该点上扩展表)。您的测试在我的chrome浏览器上实际上是无效的-它不会显示相同的性能下降

我写了一些测试用例 和


希望这有帮助

我不确定你的结果是否与画布的大小直接相关。它还能是什么?画布的大小是我唯一要改变的。我试了很多不同的尺寸。在255x250(或300x212)以下是平滑的,在宽度或高度上添加一个像素,帧速率将下降到三分之一。在这两种情况下,我画的像素数肯定是相同的。您的测试假设
requestAnimationFrame
将始终以一致的间隔进行解析,但事实并非如此。虽然FF构建可能有问题,但我认为测试不能完全依赖。例如,我在每个不同的测试中得到+/-10 fps的方差,没有明显的原因(Chrome 24,Win 7)。我建议更多地运行测试,可能会更改测试的运行顺序,然后您可能能够确定一些相关性。问题不在于jsperf!问题发生在一个独立的HTML文件中,也就是说,我正在绘制的动画变得超级急促。我只是做了一个jsperf来演示它。(联合国?)幸运的是,这个问题似乎只发生在某些系统上。(顺便说一句,测试测量从requestAnimationFrame调用到回调完成的平均时间,我通常会在这段时间发出另一个调用。这是我感兴趣的实际数字,因为它限制了最大帧速率。)jsPerf使用的动画是否与问题代码中的动画相同?它不是clearRect,我刚刚添加了两个示例HTML文件,它们解决了这个问题,但没有使用clearRect。两者所绘制的像素数完全相同。事实上,clearRect不应该有什么区别,因为它基本上只是a
memset
幕后,b)在jsperf中,我总是清除200x200像素,c)即使我要绘制更多像素,在1px宽画布上的任何操作都只需要多花费约1/250=0.4%的时间(而不是200%)。