5

我正在开发一个动画库,每隔一段时间我都会运行一次基准测试,看看我在某些功能上获得了多少收益或损失。最近我遇到了一件让我很困惑的事情,也许有更多知识的人可以为我解释一下。

之前的表现:

  • 铬:〜4460个精灵@ 30fps
  • Safari:~2817 个精灵 @ 30fps
  • FireFox:~1273 个精灵 @ 30fps
  • iPhone 4S:~450 @ 30fps

现在的表现:

  • Chrome:〜3000个精灵@ 30fps
  • Safari:~2950 个精灵 @ 30fps
  • FireFox:~1900 sprites @ 30fps(在垃圾收集变得过于分散注意力之前)
  • iPhone 4S:~635 @ 30fps

所以你可以看到,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();

};

更新

所以我下载了旧版本的 Chrome (25.0.1364.5),并运行了我的基准测试: 前

然后我在最新版本的 Chrome 中重新运行: 后

显然 Chrome 已经改变了。是故意的吗?我不知道。您可以看到,在旧版本的 Chrome 中,我实际上比原来的 4460 获得了更多的性能(+ ~400,我的优化肯定奏效了),但您也可以看到它让我悬停在 100% 的 cpu 使用率。2x cpu 几乎是屏幕上的 2x 对象。

4

1 回答 1

1

更新

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 的行为方式。


所以我弄清楚这里发生了什么。并不是说性能发生了变化,我仍然可以以 30fps 的速度在屏幕上显示 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());
        }
    }

出于某种原因,大约 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);
};

希望这可以帮助其他人。

于 2013-09-11T16:13:48.527 回答