Changing canvas performance in Chrome

I work on an animation library, and every once in a while I run a test test to find out what part of the profit or loss I get with certain functions. Recently, I came across something that puzzled me, maybe someone with a lot of knowledge can highlight this for me.

Performance up to:

  • Chrome: ~ 4460 sprites @ 30fps
  • Safari: ~ 2817 sprites @ 30 frames per second
  • Firefox: ~ 1273 sprites @ 30fps
  • iPhone 4S: ~ 450 @ 30fps

Formation Now

  • Chrome: ~ 3000 sprites @ 30fps
  • Safari: ~ 2950 sprites @ 30fps
  • FireFox: ~ 1900 sprites @ 30 frames per second (before garbage collection becomes too distracting)
  • iPhone 4S: ~ 635 @ 30fps

So, you can see that Chrome has been hit hard by performance, while every other browser seems to have improved a bit over this time. The biggest thing that I notice and what I think is the answer that CPU usage seems to have died out in Chrome (I swear before I can rise by almost 90%, now its maximum is about 60%). Most processors are used to call drawImage() , and I'm not sure I can do anything to optimize it.

If this is just a problem, when Chrome is now restricting the use of my processor, I'm fine with that.

Any insight would be greatly appreciated ...

 _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(); }; 

UPDATE

So, I downloaded the old version of Chrome (25.0.1364.5) and performed a test test: Before

Then I repeat in the latest version of Chrome: After

Clearly, Chrome has changed. Was it on purpose? I dont know. You can see that in the old version of Chrome, I actually got more performance compared to my original 4460 (+ ~ 400, my optimizations must have worked), but you can also see that this allows me to gain 100% - processor 2x cpu is almost a 2x object on the screen.

+4
source share
1 answer

Update

setInterval has no problem. Only with requestAnimationFrame . This, after all, makes such a sense. requestAnimationFrame already throttles things to 60 frames per second, which I did not know and cannot find information that Chrome (others?) throttled it to 30 (60/2), and then 20 (60/3)) and probably , 15 (60/4) ... this synchronizes it with 60 Hz, so you never get 40 frames per second, which looks strange because it does not synchronize with the screen refresh rate.

That explains a lot. I really enjoy the processor savings that provides us.

Update

An example without my code ... http://www.goodboydigital.com/pixijs/canvas/bunnymark/ , if you run this in Chrome ... you will see a point when it jumps from ~ 60 frames per second right to 30 frames in give me a sec. You can continue to add more rabbits, pixy can handle this ... Chrome adjusts fps. This is not how Chrome should behave.


So, I realized what is going on here. It's not that the performance has changed, let's say I can get 4800 objects on the screen at 30 frames per second. It seems that the way Chrome tries to optimize the end-user experience has changed. In fact, it reduces the speed to 60 frames per second to ~ 30 frames per second (29.9 frames per second according to dev tools), which leads to if(fps>=30) returns 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()); } } 

For some reason, about 2800 objects, Chrome throttles up to 30 frames per second instead of trying to go as fast as possible ... Therefore, if I run the benchmark with 4800 objects, it will be with perfectly matched 29.9fps.

fps meter

(you can see here that its 60fps or 29.9fps does not have a real time span, the only thing that changes is how often it switches)

This is the code used to synchronize the scene ...

 _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); }; 

Hope this helps someone else along the way.

+1
source

Source: https://habr.com/ru/post/1501520/


All Articles