HTML canvas is widely used in games and complex image visualization. However, as websites and applications push canvas rendering to the limit, performance becomes a problem.

Here are some suggestions to improve performance:


Pre render similar shapes or duplicate objects on off screen canvas

When we find that there are many complex drawing operations in every frame, please consider creating an off screen canvas, drawing the image on this canvas once (or every time the image changes), and then drawing the canvas beyond the line of sight on each frame.

myEntity.offscreenCanvas = document.createElement("canvas");
myEntity.offscreenCanvas.width = myEntity.width;
myEntity.offscreenCanvas.height = myEntity.height;
myEntity.offscreenContext = myEntity.offscreenCanvas.getContext("2d");

myEntity.render(myEntity.offscreenContext);

Avoid floating-point coordinates and replace them with integers

When we draw an object without an integer coordinate point, sub-pixel rendering is generated.

ctx.drawImage(myImage, 0.3, 0.5);

In order to achieve the anti aliasing effect, the browser will do additional operations. To avoid this, make sure that when you call the 'drawimage()' function, you use the 'math. Floor()' function to round all coordinate points.

Do not scale an image when using DrawImage

Cache different sizes of images in off screen canvas instead of using 'drawimage()' to scale them.


Use multi-layer canvas to draw a complex scene

In daily development, we may find that some elements change or move constantly, but some elements will remain unchanged forever, such as appearance. An optimization of this situation is to create different layers with multiple canvas elements.

For example, you can create an appearance layer at the top level, and it will only be drawn when the user enters. You can create a game layer with constantly updated elements and a background layer for those less updated elements.

<div id="stage">
  <canvas id="ui-layer" width="480" height="320"></canvas>
  <canvas id="game-layer" width="480" height="320"></canvas>
  <canvas id="background-layer" width="480" height="320"></canvas>
</div>
 
<style>
  #stage {
    width: 480px;
    height: 320px;
    position: relative;
    border: 2px solid black
  }
  canvas { position: absolute; }
  #ui-layer { z-index: 3 }
  #game-layer { z-index: 2 }
  #background-layer { z-index: 1 }
</style>

Using CSS to set large background map

Most games have a static background map, using a static <div> element, combining the background feature, and placing it after the canvas element.

This avoids drawing large images on the canvas at every frame.

Zoom canvas with CSS transforms feature

The CSS transforms feature is faster because it calls GPU.

Best of all, do not enlarge the small canvas, but shrink the large one. For example, in Firefox, the target resolution is 480 x 320 px.

var scaleX = canvas.width / window.innerWidth;
var scaleY = canvas.height / window.innerHeight;

var scaleToFit = Math.min(scaleX, scaleY);
var scaleToCover = Math.max(scaleX, scaleY);

stage.style.transformOrigin = '0 0'; //scale from top left
stage.style.transform = 'scale(' + scaleToFit + ')';

Turn transparency off

When the game drawing we developed does not need to use transparency, we can use htmlcanvaselement. Getcontext() to create a drawing context, and set the alpha option to false. This option helps the browser optimize internally.


More optimization details

-Gather the function calls of the canvas together (for example, do not draw multiple separate lines when drawing a polyline)
-Avoid unnecessary canvas state changes
-Render different points in the canvas, not the whole new state
-Avoid the shadowblur feature as much as possible

  • Avoid text rendering as much as possible
  • Use different methods to clear the canvas. Clearrect() or fillrect() or adjust canvas size
  • To draw an animation, please use window. Requestanimationframe() instead of window. Setinterval()
  • Use large physical libraries with caution

More information

Improving HTML5 Canvas Performance – HTML5 Rocks
Optimizing your JavaScript game for Firefox OS – Mozilla Hacks