Why does chrome struggle to display lots of images on a canvas when the other browsers don't? Why does chrome struggle to display lots of images on a canvas when the other browsers don't? google-chrome google-chrome

Why does chrome struggle to display lots of images on a canvas when the other browsers don't?


In Canary this code freezes it on my computer. As to why this happens in Chrome the simple answer is that it uses a different implementation than f.ex. FF. In-depth detail I don't know, but there is obviously room for optimizing the implementation in this area.

I can give some tip however on how you can optimize the given code to make it run in Chrome as well :-)

There are several things here:

  • You are storing each block of colors as images. This seem to have a huge performance impact on Canary / Chrome.
  • You are calling requestAnimationFrame at the beginning of the loop
  • You are clearing and rendering even if there are no changes

Try to (addressing the points):

  • If you only need solid blocks of colors, draw them directly using fillRect() instead and keep the color indexes in an array (instead of images). Even if you draw them to an off-screen canvas you will only have to do one draw to main canvas instead of multiple image draw operations.
  • Move requestAnimationFrame to the end of the code block to avoid stacking.
  • Use dirty flag to prevent unnecessary rendering:

I modified the code a bit - I modified it to use solid colors to demonstrate where the performance impact is in Chrome / Canary.

I set a dirty flag in global scope as true (to render the initial scene) which is set to true each time the mouse move occur:

//globalvar isDirty = true;//mouse move handlervar handleMouseMove = function (eventArgs) {    // other code    isDirty = true;    // other code};//render loopfunction renderLoop() {    if (isDirty) {        clearCanvas();        renderCanvas();    }    stats.update();    requestAnimFrame(renderLoop);}//in renderCanvas at the end:function renderCanvas() {    // other code    isDirty = false;}

You will of course need to check for caveats for the isDirty flag elsewhere and also introduce more criteria if it's cleared at the wrong moment. I would store the old position of the mouse and only (in the mouse move) if it changed set the dirty flag - I didn't modify this part though.

As you can see you will be able to run this in Chrome and in FF at a higher FPS.

I also assume (I didn't test) that you can optimize the clearCanvas() function by only drawing the padding/gaps instead of clearing the whole canvas. But that need to be tested.

Added a CSS-rule to prevent the canvas to be selected when using the mouse:

For further optimizing in cases such as this, which is event driven, you don't actually need an animation loop at all. You can just call the redraw when the coords or mouse-wheel changes.

Modification:
http://jsfiddle.net/BtyL6/10/


This was a legitimate bug in chrome.

https://code.google.com/p/chromium/issues/detail?id=247912

It has now been fixed and should be in a chrome mainline release soon.