Canvas is laggy, often for the stupidest of things. Today I will go over some tips and tricks for improving the performance of rendering to the canvas, and debunk some myths about getting a higher FPS. Being able to squeeze an extra couple of FPS out of your game can often be the breaking or making point for performance. Some of these techniques can be harder to implement than others, but hopefully you will be able to optimize your HTML5 games for the best possible performance. So, here we go!

(adsbygoogle = window.adsbygoogle || []).push({});

Floating Point Coordinates

When rendering an image, preforming translations on the canvas, or just rendering a regular rectangle, it is possible to improve your speed just a little. Don’t render them using a decimal of any kind. You can speed up rendering if you always set the X, Y, Width, and Height variables to whole numbers. This can be achieved by simply using a function like Math.floor() to round them to the lowest whole number. This prevents the screen from needing to render too many half-pixels.

Image Cashing

If you have a complex background, made up of lots of various sprites and does not need to be updated every second, try image cashing. This is like pre-rendering them to an off screen canvas every once in a while, then drawing only one image during the game loop. This can vastly increase the performance of your game depending on how many sprites you use. It is also useful for rendering canvas operations, as they can often be expensive as well. Just save an image of the whole thing, and render it when needed.

Using Request Animation Frame

Use request animation frame when possible, what it does is try and keep up with the refresh rate of the monitor. However, it only draws when ready to. So it keeps your animations at a reasonable pace. Check out more here.

Avoid Using save() and restore()

If possible, it is best to avoid preforming the save and restore functions on the context. Instead of using save and restore, just reverse the transformation manually. For example, if you rotate the canvas 45 degrees, then just rotate it -45 degrees when you are finished with the animation. This saves lots of time, as preforming those operations on the canvas can be especially costly.

Rendering to an off-screen canvas

Lots of people believe that rendering to a canvas that is off screen is much faster then one onscreen, because it is just in the memory. However, it only takes  marginally less time, hardly enough to be noticeable. The true power this brings is having separate FPS for separate parts of the screen. You want your player and enemies to be battling in full 60 FPS glory? No problem, You don’t need to update the GUI 60 FPS? don’t only update it at 20 FPS. This is a method of image cashing that is very effective in fast paced games. I have heard this method referred to as Fire Cashing. By using this, it effectively splits the screen into parts to be rendered at different speeds. Making it possible to show thousands of sprites in a background, while having the mane game being preformed at full speed.

Only render whats on screen

Because rendering off-screen is nearly as slow as rendering on screen, you need to make sure that you only render what the player will see. You can implement this with basic collision detection between the image, and the screen. If they don’t collide, then you just don’t render the image. However, if they do overlap , then you need to render it. and almost no processing power is lost.

Garbage Collection

Garbage collection can be one of the biggest bottlenecks in JavaScript performance. The garbage collector basically takes all variables, objects, and such that are no longer in use and deletes them freeing up space in the memory. This process can take up to 100ms , and cause a major lag spike in your game. The best way to avoid this is to use techniques such as object pooling, or just avoid creating new objects as much as possible. we create new objects every time we make a local variable, or even use the return statement. So it is best to avoid using these things every frame. As doing so will just pile work onto the GC.


  • I really like this article. It outlines the exact reasons why I created my Canvas library. I worked really hard on learning how to do canvas transforms using setTransform manually. It has greatly improved my development time and performance too.

    Immutable canvas instructions that compile down to simple property sets/gets and function calls happen to be very performant. Please check it out!

Comments are closed.