Search code examples
htmlgoogle-chromecanvasinternet-explorer-11

Increasing size of the canvas by one pixel is causing performance regression in Chrome


My app draws same figure on the canvas multiple times. We figured out that we could draw it once on the hidden canvas and them just copy it to the target canvas. I am doing some perf comparison. And I am facing some weirdness that I can't explain.

Here it is in a nutshell: I have a test with two canvases of the same size. In the first canvas I draw figures multiple times. On the second: I draw on the hidden canvas first, then I copy it into visible canvas. The result should be the same. Here is the fun part: Approach with hidden canvas works fine with size of the canvas 400x164. It is 60% faster that drawing each figure separately. But once I increase size by once pixel to 400x165 - bam! Stamping is 60% slower in Chrome. In IE it is still faster (ask me how I found out that 164-165 threshold).

Here are the links to JsPerf tests:

Chrome 46.0.2490.80 32-bit on Windows Server 2008 R2 / 7 64-bit

Any help is appreciated.

enter image description here


Solution

  • The answer is this and it is unfortunately stupid. I've been baffled by this for years. Your question helped me find the answer.

    If and only if a canvas contains >= 60,000 pixels, will Chrome allow hardware acceleration.

    I had a 200x200 mini-map sitting ontop of a webgl app. The webgl app would be rendering 150,000 polygons no problem at 60fps. Once the player began moving, the framerate would drop to ~30fps. Disabling the minimap would keep things at a smooth 60fps. I was surprised my tiny little super basic minimap would cause such a massive hit.

    After searching on SO for a solution (and not really finding one), I began playing with the posted jsfiddles. Canvas size seemed to make all the difference. In one particular fiddle (from HTML5 drawImage slow on Chrome), I tried a size of 256x256 (area of 65,536), ran terribly. Tried 257x257 (area of 66,049) ran roughly 6x faster...

    So I tried my minimap at 257x257 (used CSS zoom to shrink it down to the appearance of original size). Ran great, almost 0 performance hit when moving.

    So there it is. Google chose a threshold of 60,000 pixels in order for hardware acceleration to kick in.

    Annoying.

    Version 63.0.3239.84 (Official Build) (64-bit)