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:
- The reference canvas implementation that redraw the background on every frame.
- The more complex scrolling implementation.
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)
| Browser | Canvas system load | Scrolling system load |
|---|---|---|
| Chromium 12.0 | 66% (B:58%, X:7%) | 38% (B:20%,X:18%) |
| Opera 11.50 beta | 104% (B:90%, X:14%) | 49% (B:34%, X:15%) |
| Firefox 5.0 | 86% (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:
| Browser | Performance increase |
|---|---|
| Chromium 12.0 | 42% |
| Opera 11.50 beta | 52% |
| Firefox 5.0 | 32% |
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.