目前我在一个名为“隧道2”的小型js / canvas游戏上工作(我很确定这是一个众所周知的旧版本,但我知道没有)。你可以try the game here。另外,我推荐使用chrome。
所以,我开发了谷歌浏览器,它工作正常,即使在我糟糕的旧机器上。我大概30帧左右。在我的同事笔记本上它产生> 100fps。到现在为止还挺好。 safari似乎也运作良好。
接下来我在firefox 4 beta 10上试了一下......我只得到了~10 fps。但是ff4肯定不是 慢,对吧?
我开始调查了。这是我的主要循环:// starts the game loop
this.run = function () {
this.draw();
var
t = this,
timeLastTurn,
timeThisTurn = (new Date()).getTime()-1;
var loop = function () {
timeLastTurn = timeThisTurn;
timeThisTurn = (new Date()).getTime();
// dt is the time difference between this turn and the last turn
var dt = timeThisTurn - timeLastTurn;
// player movement etc
t.turn(dt);
// draw game state
var res = t.draw();
// if there's no collision, game over
if (!res.collision)
t.setState(2);
// actually, there's a browser dependent minimum timeout that
// may vary. but even if it's more than 10ms - we don't care.
// game should run at the same speed (though not as smooth)
if (gameState == 1)
timer = window.setTimeout(loop, 5);
// just debug output
debug = dt;
}
// start the main loop
loop();
}
我观察到了什么:
不出所料,this.draw();
是迄今为止最昂贵的功能,但它只需要几毫秒(实际上大约为5),在chrome ... 以及firefox 上。没有接近> 100毫秒,它只需要10fps!整个loop()
调用也不多,在firefox上花费的时间不到10毫秒!
如果您调查dt
,可以看到差异。它应该是time-loop() - 超时+ 5ms(或浏览器最小超时值)。
但是在ff4上,该值接近180ms,即下一个超时事件在170ms而不是5ms内发射!如果你玩的时间稍长,单帧(gc,肯定)会达到~800ms,然后再回到180ms。
有人知道罪魁祸首是什么吗?
是GC的责任吗?一方面我不认为我创造了太多短暂的变量,嘿,每次150ms!?但当然可能是。有一个简单的方法来检查这个? chrome profiler记录gc次数(约0.10%),但是firebug profiler没有。
也很有趣:游戏运行速度更快(~5fps),启用了firebug。
添加。 info:使用setInterval而不是setTimeout不应该也不会改变任何内容。
答案 0 :(得分:0)
我可以确认它不适用于FF 3.6.13 OS X.
在我开发Snake JS期间,我发现setInterval
行为存在差异。你应该看看这个:
var timer = setInterval(fn, 500)
// ...
timer = setInterval(fn, 500)
// Since I didn't use clearInterval() I now have two timers running in FF.
我发现你没有使用setInterval
,但也许它与setTimeout
类似?
答案 1 :(得分:0)
我遇到了一些高端画布应用程序的主要问题,我在构建和使用firefox 6及以下时已经使用过。有许多问题涉及性能以及firefox中的支持不佳或完全不支持的画布功能。他们确实在firefox 7中做了大量更新,改进了许多您可能会注意到的问题。这有点烦人,我需要在一个基于Facebook的大型基于画布的应用程序上支持ff4,这个应用程序在6及更低版本中并不是那么好用。我已经做了很多事情来尝试和破解性能相关的问题,而且很难找到大多数事情的解决方案。