eri*_*sti 5 javascript performance google-chrome html5-canvas
我正在制作动画库,每隔一段时间就会进行一次基准测试,以查看某些功能带来的收益或损失。最近,我遇到了一些让我感到困惑的事情,也许有更多知识的人可以为我提供帮助。
之前的表现:
现在的性能:
因此,您可以看到,Chrome在性能上大受打击,而其他所有浏览器在这段时间内似乎都变得更好。我注意到的最大问题是答案,那就是Chrome中的CPU使用率似乎已被降低(我发誓我可以提高到90%之前,现在最高达到60%)。大部分的CPU都用于该drawImage()
调用,但我不确定我可以做些什么来优化它。
如果仅是Chrome现在限制我的CPU使用率的问题,那很好。
任何见识将不胜感激...
_s.Sprite.prototype.drawBasic = function() {
var s = this.ctx;
if(s.globalAlpha!=this._alpha) s.globalAlpha = this._alpha;
var width = this.width;
var height = this.height;
var x = this._x;
var y = this._y;
if (_s.snapToPixel) {
x = this._x + (this._x < 0 ? -1 : 0) | 0;
y = this._y + (this._y < 0 ? -1 : 0) | 0;
height = height + (height < 0 ? -1 : 0) | 0;
height = height + (height < 0 ? -1 : 0) | 0;
}
var frame = this.sequence[this.frame] || 0;
var sheetY = frame + (frame < 0 ? -1 : 0) | 0;
var sheetX = (frame - sheetY) * this.spriteSheetX || 0;
s.drawImage(this.bitmap.image, this.bitmap.frameRect.x2 * sheetX, this.bitmap.frameRect.y2 * sheetY, this.bitmap.frameRect.x2, this.bitmap.frameRect.y2, x - (width * this._scaleX) * this.anchorX, y - (height * this._scaleX) * this.anchorY, width * this._scaleX, height * this._scaleY);
this.updateFrame();
};
Run Code Online (Sandbox Code Playgroud)
更新
因此,我下载了旧版本的Chrome(25.0.1364.5),并运行了基准测试:
然后,我重新运行了最新版本的Chrome:
显然,Chrome已更改。是故意的吗?我不知道。您可以看到,在旧版本的Chrome中,我实际上比原来的4460有了更高的性能(+〜400,我的优化必须已经奏效),但是您也可以看到它使我能够在100%的CPU使用率上徘徊。2x cpu几乎是2x屏幕上的对象。
更新
setInterval
没有这个问题。仅发生在requestAnimationFrame
. 这终于有意义了。requestAnimationFrame
已经将速度限制为 60fps,我不知道,而且似乎找不到任何信息,Chrome(其他?)将其限制为 30 (60/2),然后是 20 (60/3),可能15(60/4)...这使其与 60hz 保持同步,因此您永远不会得到看起来很奇怪的 40fps,因为它与屏幕刷新率不同步。
这解释了很多。我真的很享受这为我们带来的 CPU 节省。
更新
一个没有我的任何代码的例子... http://www.goodboydigital.com/pixijs/canvas/bunnymark/如果你在 Chrome 中运行这个...你会看到它从 ~60fps 直接跳到 30fps 的点。你可以继续添加更多的兔子,pixy 可以处理它......Chrome 正在限制 fps。这不是 Chrome 过去的行为方式。
所以我知道这是怎么回事了。这并不是说性能发生了变化,我仍然可以以 30 fps 在屏幕上显示 4800 个对象。改变的似乎是 Chrome 尝试优化最终用户体验的方式。它实际上将速度从 60fps 降低到约 30fps(根据开发工具为 29.9fps),这会导致if(fps>=30)
返回 false:
stage.onEnterFrame=function(fps){ // fps = the current system fps
if(fps>=30){ // add astroids until we are less than 30fps
stage.addChild(new Asteroid());
}
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,在 2800 个对象左右,Chrome 会降低至 30fps,而不是尝试尽可能快地运行...因此,如果我以 4800 个对象开始基准测试,它会保持在非常一致的 29.9fps。
(您可以在这里看到它要么是 60fps 要么是 29.9fps,没有真正的中间值,唯一改变的是它切换的频率)
这是用于阶段计时的代码......
_s.Stage.prototype.updateFPS = function() {
var then = this.ctx.then;
var now = this.ctx.now = Date.now();
var delta = now - then;
this.ctx.then = now;
this.ctx.frameRatio = 60 / (1000 / delta);
};
Run Code Online (Sandbox Code Playgroud)
希望这对其他人有帮助。