Boris Smus

Software Designer

Performance of Canvas versus SVG

At the core of the traditional HTML/CSS developer’s toolkit is a set of nested boxes describing offset, margin, border and padding, known as the box model. Variations on the box theme are sufficient to describe most page layouts, but in some complex applications, it’s necessary to render something more interesting, like diagonal lines, or polygons. There are currently two relatively well-supported web graphics technologies: SVG and Canvas. There are significant performance differences, however, which I would like to discuss in this article.

Scalable Vector Graphics (SVG) is by far the oldest of the two. It is a declarative, graphical language used to describe geometrical primitives via DOM elements. SVG was drafted in the late 90s, and the latest version of SVG, version 1.1 was finalized in 2003. It took 3 more years for it to be incorporated into shipping versions of Mozilla Firefox and Safari. Unfortunately, the length of the SVG adoption process caused the web development community to seek other options. The HTML5 Canvas element was introduced as a much simpler alternative to graphics on the web. It provides an image-like graphics context which can be accessed via a set of javascript calls, similar to a 2D subset of OpenGL. It was originally introduced by Apple in WebKit builds, but is now supported in Mozilla Firefox as well.

I produced some metrics to compare the two technologies in terms of performance by writing a Javascript program for collecting performance data. This program draws rows of circles onto a fixed-size drawing area in SVG and in Canvas, and then compares how long various operations take. It also records the duration to create the initial drawing context, to render the scene and to clear the scene. A test runner invokes the benchmark with the following variables: number of circles, drawing area dimensions and circle size. Each of these variables are varied independantly and automatically resulting in the following observations:

Varying the number of objects

Here are the results of the first fruitful experiment, which clearly shows that SVG performance degrades quickly (exponentially on Safari?) in the number of objects, but Canvas performance remains at a near-constant low. This makes sense, since Canvas is just a bitmap buffer, while SVG has to maintain additional references to each object that it renders. Also, though not pictured, note that performance in clearing an SVG element also decreases in the number of drawn objects.

Varying drawing area height

When varying the size of the drawing area, canvas performance degrades significantly, while SVG performance is completely unaffected. Canvas rendering performance seems to degrade linearly in the number of pixels in the canvas area. Not pictured on the graph is clear performance for large canvases, which also suffers linearly in pixel count.

I did not include the graph resulting from varying circle size as it had no significant impact on render time. Another interesting observation is that creating the canvas element takes a mysterious 10 ms on Firefox, but not on Safari. This is not significant unless you are dealing with large numbers of canvas elements.

Whether or not you use Canvas or SVG mostly depends on your specific application. For graphically simple applications like bingo, you might find plain HTML elements sufficient. A graphics-intensive game, where many objects are redrawn all the time is probably best implemented in Canvas. On the other hand, applications like map viewers may involve large rendering areas and might lend themselves better to SVG.

As always, please comment if something is unclear, inconsistent, boring or omitted. Thanks!

17 comments:

Allen Pike

This is awesome. As I suspected, Safari 3’s behaviour on simple rendering tasks is faster than Firefox’s, but it’s worst-case behaviour is much worse. I’d be interested to see the addition of recent Webkit/Canvas for drawing area, and Webkit/SVG for number of objects.

on January 21st, 2009 at 11:39 am
Dmitry

Sweet post Boris!..

I guess the figures back up the design decisions.. container size is no challenge for a vector image, but the additional metadata drags the performance figures down when there are a lot of entities. Makes sense.

on January 21st, 2009 at 4:21 pm
Boris

@Allen: good idea. but the trouble with recent webkit builds is their relative instability. im not sure how even the performance is either. but ill try with a good-ish build and update.

@Dmitry: thanks! yep as you say, this post can be shortened to a sentence. svg doesn’t scale well with number of elements, and canvas doesn’t scale well with rendering area :)

on January 23rd, 2009 at 8:58 am
Torsten

Hi Boris,

great post and some interesting observations. I’d like to see how Opera fits in between the other 2 major players though.

on January 25th, 2009 at 12:53 pm
Boris

thanks. i’ll try to rev this article to include more browsers.

on February 11th, 2009 at 3:17 pm
Toby Hede

It would be interesting to see the performance of canvas with an event model tied. I have been playing with ProcessingJS and to detect events you basically need to iterate through your entire scene graph to detect if the current mouse position falls within the object coords. Only just started playing with this, but I suspect that tying in events of any non-trivial nature will change the canvas efficiency dramatically.

on May 10th, 2009 at 4:02 am
Unterbahn » Blog Archive » SVG vs.

[...] Via Boris Smus [...]

on August 3rd, 2009 at 7:32 am
Al

@Toby you can break complex maps into grids. Then you can alias your objects onto the grid and every time the mouse moves, you only need to check whether the mouse is within n squares. If the mouse is over grid square {x:1,y:1} you can then you can check for square bounding of objects inside the grid location without iterating over your whole set of objects. If you then have a collision inside your square/box object bounds, you can further check within the polygons of the objects who’s squares bounds overlap the cursor.

This way you check minimal objects per cycle and only calculate more complex ray-casting type checks when you encounter an object within the current quadrant. Obviously this method would become worth the computation as soon as you have about twice as many objects as you have quadrants; that being said there would be slightly more memory usage due to the extra object linking and grid code, but still… only slightly.

on September 15th, 2009 at 6:14 am
Millennium » Blog Archive » VML, SVG, Canvas: вчера, сегодня, завтра

[...] вопросов производительности не возбраняется обратиться к исследованию, установившему закономерность в обществе [...]

on November 27th, 2009 at 4:35 pm
why not print

What year is this page?

on December 16th, 2009 at 9:43 pm
Thomas Auzinger

What year is this page, indeed (asked on 22JAN2010)

on January 22nd, 2010 at 8:56 am
Boris Smus

2009. Thanks for pointing out the bug!

on January 23rd, 2010 at 10:46 am
Julian

For the number of object test, I feel this is a bit unfair to SVG.

In the source code, the canvas test reuse the same context object and adding more circle in it. While the case for SVG, it have to create an element for each circle.

Another thing is each circle in the SVG can be manipulated individually, while you cannot do that with drawing multiple cirlce on the same canvas.

I think it might be better if the number of object test is drawing circle on new canvas element.

on February 11th, 2010 at 3:26 am
SVG vs CANVAS | A fronteira final

[...] significativas de desempenho entre Canvas e SVG. O resultado do experimento descrito no link (http://www.borismus.com/canvas-vs-svg-performance) é que: Canvas é mais adequado para um “gráficos intensivos” onde o objeto são os [...]

on April 8th, 2010 at 5:42 am
Publishing with Silicon » Blog Archive » Internet Explorer to support SVG? - Max Dunn's electronic publishing blog: reconciling information and rendition technologies

[...] can accomplish most or all of the core Flash capability that everyone (other than Adobe) wants. SVG and Canvas seem to have complimentary performance depending on what you’re doing. Still, who wants to learn how to do everything two different ways? Perhaps those railroading HTML5 [...]

on May 5th, 2010 at 12:47 am
Anonymous

It seems to me, canvas is the bitmap engine (like photoshop, jpg etc), while svg is the vector engine (ai, eps). A marriage between the two allowing both vector shapes and bitmap images to coexist would be the best solution. Has anyone tried to blend them together? Can they overlap? Can you mask a bitmap image with a vector image? That would be sweet.

The other issue is content creation. Flash creates a tool that outputs easily. For either of these two new innovations to become mainstream they need to support of the ‘creative’ community.

on May 15th, 2010 at 8:21 pm
Canvas or SVG? | HTML 5 stars

[...] good to have a quick reference as to when to use what. If you want a more in depth comparison go here Good resources to start with canvas I, personally followed the Mozilla Canvas (here) and found [...]

on May 18th, 2010 at 3:38 pm

speak your mind