2011-06-27

HTML5 Canvas performance: is it possible to avoid a full redraw with a moving background?

Playing the multiplayer flash game Realm of the Mad God I was wondering how to implement map scrolling with Canvas. Knowing how slow Canvas draw images, the simple approach of redrawing everything for every frame sounded quite inneficient.

So using the javascript library called Sprites.js I created what I called a map scroller script that use 9 half-size canvas surface to draw the scrolling background and then move those canvas in the same direction to create the scrolling effect. Here is the 2 versions to compare:

Then I monitored the CPU usage from different browsers. This table represent the total load of the system created by the animation on my linux box. (B:Browser load, X:Xorg load)

BrowserCanvas system loadScrolling system load
Chromium 12.066% (B:58%, X:7%)38% (B:20%,X:18%)
Opera 11.50 beta104% (B:90%, X:14%)49% (B:34%, X:15%)
Firefox 5.086% (B:62%, X:24%)42% (B:21%, X:20%)

Some of the load seeme to be shifted to the XOrg server when the scolling version is used. I assume that XOrg has to do more composition work with the 9 canvas. Despite this there is a clear decrease in total system load.

The perfomance increase given by 1 - (Scrolling load / Canvas load) is the following:

BrowserPerformance increase
Chromium 12.042%
Opera 11.50 beta52%
Firefox 5.032%

So it seems that this method is a valid way to yield a nice performance boost in all browser for a tile scroller game or any parralax effect. It also highlight the slowliness of the Canvas API when it comes to drawing images.

I will release the this code soon as part as the Sprite.js library.