Hacker News new | past | comments | ask | show | jobs | submit login
SVG vs Canvas, what format to choose? (scriptol.com)
33 points by scriptproof on May 23, 2011 | hide | past | favorite | 22 comments

The big difference is that for SVG the structure "remains", while with canvas it is "forgotten". That makes SVG more complex, but also easier to manipulate.

Here's an SVG site I wrote (it'll take a while to load and will only display in recent browsers). The way that it responds to mouse-overs is (relatively) easy to program in SVG because you can associate events with structure in the image - http://practi.cl/en/proj/pysrc/lepl/lepl#pkg-tab=b-dependenc... (it's showing package dependencies for a Python library).

To do something similar with canvas you would redraw sections instead of simply changing the properties of arcs, etc (and handling user clicks is lower-level - instead of getting the action associated with some "thing" in the image, you get a coordinate). Which is "best" depends on the application. The link above makes more sense in SVG because you've got logically distinct, overlapping components. But if you want a more static image, canvas is probably going to be simpler.

On the topic of SVG and Canvas, I think it would be really useful if Canvas had a method similar to drawImage but instead could draw svg.

for example

var circle = document.createElementNS("http://www.w3.org/2000/svg, "circle"); circle.setAttribute("style", "fill:green"); circle.setAttribute("cx", 50); circle.setAttribute("cy", 50); circle.setAttribute("r", 25);


I think then we could have the best of both worlds, define complex shapes in svg, but use canvas for rendering. The advantage over just using svg is that every shape is in the dom, so if you want to draw 1000 similar shapes the dom gets cluttered.

Yes, that'd be very useful as a built-in. In the meantime, you could use a SVG-on-canvas renderer such as:


Some browsers can render images in canvas that are actually SVG files, but support is a bit patchy outside Webkit, and there are some other issues, but may work for you. http://www.svgopen.org/2010/papers/62-From_SVG_to_Canvas_and...


Looks great in Chrome for me, aliased in Firefox.

I use both. I create SVG files with Inkscape (if and only if I need to draw some complex shapes) and then I display them using the Processing language (the javascript port:)


The Processing parser generate (fast) javascript code on the fly the can be accessed from external scripts. You can mix processing with javascript.

To add a quick but slightly more detailed clarification, between the concepts of Canvas as bitmap and SVG as vectors:

An image in HTML canvas, is stored as a matrix of pixels. Individual pixels in the matrix, can be accessed and modified with canvas API methods.

The canvas drawing API allows to draw vector graphic primitives on the canvas, but these are immediatly rasterized as pixels. So the image is always a bitmap.

In SVG, an image is stored as a set of graphics primitives. There is a primitive that can hold external bitmap images. But there is no way to read or modify individual pixels. Only parameters in the primitive definition can be accessed.

In the Canvas it is possible to operate directly over pixels. In SVG only the mathematical definitions of the shapes primitives can be modified. So complex pixel procesing algorithms are possible with Canvas, but not with SVG.

> In terms of speed, Canvas will always win because the SVG content must be integrated into the document and the DOM, even when it is generated dynamically, which slows it down.

I think this is misconception based on (mis)use of SVG as if it were canvas, where people destroy and re-create whole DOM each time picture changes. That's not how SVG is meant to be used — SVG is best when updated incrementally and animated declaratively.

SVG has advantage (and should be faster in a decent implementation) when you animate complex shapes: (linear) animation in SVG doesn't require touching of large number of DOM nodes — you just update an attribute of a single group. With SMIL you just trigger the animation and don't touch DOM again. This allows browser to handle repainting natively and cache group/shape bitmaps.

OTOH animation on canvas requires issuing hundreds of canvas drawing commands, from JavaScript, each frame, repeatedly.

On canvas if you want to move layer that is behind another one, you have to redraw all top layers. In SVG browsers are able to cache layers and use (GPU-)accelerated compositing. I can't find the link, but I've seen demo from Opera where they allow author to declare which parts of SVG change rarely and can be cached as bitmaps.

> Because SVG is made of XML tags

Except for SVG path data of course, which are strings of 1-character commands (with parameters interspersed) in XML attributes. "M 100 100 L 300 100 L 200 300 z"? Why yes, I missed perl, thank you very much.

And don't forget: case matters…

Another SVG vs Canvas paper from SVGOPEN '09 that I found useful while working early this year - http://www.svgopen.org/2009/papers/54-SVG_vs_Canvas_on_Trivi...

I wrote a prototype fence drawing app for ipad. Initial svg-only prototype turned out to be extremely slow. While in a mixed approach, svg gave flexibility of programming interactions while canvas helped me quickly render alterations in polygons of the fences as one touched and dragged.

Bottomline - SVG performance degrades as number of objects, Canvas performance degrades as size of the canvas. Mix both to get the best.

I didn't learn anything from this, but I've been using d3.js most of the weekend to help me build dynamic SVGs for a project. With d3 handy, I say SVG. :)

Or Raphaël

If you have a graph with large number of elements, Canvas scales better. I have built a plotting library in Canvas which can plot about 25000 points (typical requirement with genomic data) in a couple of seconds. Doing this in SVG will not be viable.


I've written quite a number of graph/visualization UI controls myself over the years (mostly on the desktop) and in the course of doing so, have looked at many 3rd party libraries / widgets. Many of them claim to be able to do 10's of thousands of points / lines / etc; but I'm still wondering, I have yet to see an actual use for it. 25k data points = even at 1024 * 768, a point density so high that the graph is basically a big colored blob.

For infoviz (although I don't have a formal background in it), I've always taken the approach of implementing more intelligent data point selection algorithms - better selections of what points to actually display, to maximize the information the user gets out of the graph, rather than trying to push as many data points per frame. Similar to improved LoD algorithms making 3d worlds better when raw pixel throughput in the 3d rendering path can't keep up.

Anyway my question is, in what circumstances do you need to render 25k data points per frame / render loop? Aren't there clusters of 10's or 100's of them who end up obscuring each other anyway?

What about performance in different browsers? For SVG, everything is smooth in Chrome, but Firefox is pretty much slower (I'm using RaphaelJS)

I have checked on Firefox, Safari, Chrome. It is just as fast on each, takes about 2 secs to plot 25k+ points.

svg is slower on mobile browsers, and in android < 3.0 (i.e. ~96% of android devices), svg isn't supported at all

My recommendation is svg for static graphics/pictures, and canvas for animations/dynamic stuff, but keep the canvas as small as you can

how do you need to plot them / what are the requirements.

I should do some more speed testing, but e.g. it's possible to get SVG to draw "markers" at every point in a single polygon, and fairly quickly in some renderers.

I'd also expect SVG to be faster if you have a reasonable amount of shapes but only move one or two. In canvas you have to redraw everything yourself, with SVG you simply change the coordinates of the shapes you want to move, and the browser takes care of redrawing what is needed.

It's based on pure Canvas so there are no other requirements. I am still working on the documents but the source code is commented well. Right now it creates scatter plots but I may add other types of plots later. If you intend to help it in your application, I will be happy to work with you.

You could draw SVG markers at every point but with the DOM and everything, it just becomes very slow. protovis (a great SVG based library) mention the number 10,000 points at which SVG starts becoming unusable. I am able to plot 25k+ points.

To see something you probably won't be able to do in SVG, check http://bomomo.com/

What a pleasant and unbiased article

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact