SVG has the opposite performance profile of Canvas.
SVG hits a performance ceiling as number of elements increases.
Canvas, since it's rasterized image can handle a rasterized representation of millions of SVG elements.
However as Canvas dimension increase, it will hit a performance ceiling.
In my experience, canvas 2D also has a number-of-elements performance ceiling if you're drawing things rather than using images, which feels like it defeats the purpose.
For example, try drawing hundreds of coloured rectangles per frame. Easy, right? If you're using WebGL, or any sensible graphics API, yes. If you're using canvas, the web-browser will parse and re-parse your colour expression CSS n times per frame. Enjoy your 100% CPU usage.
> has a number-of-elements performance ceiling if you're drawing things rather than using images, which feels like it defeats the purpose.
Well you can generate your imagery programmatically and then render it to canvas as a raster image. Canvas is not purely for implementing a web based drawing app.
when you are faced with between rendering hundreds of thousands of SVG DOM element vs in memory generation of a final raster image, the latter will always be more performant.
Basically, canvas performance depends a lot on how many pixels you draw and how you draw them (blitting an image vs. drawing a gradient are very different things, obviously).
SVG performance depends on how many things in the DOM are changed at the same time (and then it's mostly dependent on how well the browser can avoid redraws – that's an area where we frequently encounter bugs when either too much or too little is redrawn). A large static image¹ manipulated only via affine transforms performs quite well; an image containing lots of different things that all vary constantly is bad. But as long as the viewport isn't too large, canvas can be a viable alternative to SVG if the visualization is simple.
This comes up on each SVG thread and I post the same comment each time (so excuse me if you've heard this from me before).
We render SVG that contain beyond 100k nodes in the browser and find that it works fine. You need to be careful with your manipulations and we've developed a couple of tricks to keep things snappy, but the final experience is great.
There's not a specific ceiling. This morning I did a quick test with 400k nodes and we sometimes get 2-3 million or more.
We only use chrome because Firefox struggled in the initial testing. Having said that, I haven't tried in anything other than chrome in ages and I'd wager the situation has changed a lot in the last couple of years.
No, in our case they're all unique elements - unfortunately for me! That demo example is actually much smaller though (2k nodes).
Here's an example with over 150k nodes [1]. To be honest, we would normally doctor documents that had this many nodes to make the experience smoother for users. You'll notice that it's a bit sluggish when you zoom in and out, but panning is the same speed regardless of number of elements, and updating elements within the document is fast too.
You can use something like `transform:translateZ(0px)` to force a subsection of the dom to exist on its own rendering layer. Then you can transform the parent nodes and they'll move the lower layer around as if it were a static picture that they don't need to redraw. I'm not sure how well this works within an svg, but you can certainly use it to do your transformations outside the svg.
ok i dug out the project I was thinking of and I was wrong - performance is fine at 10k nodes. adding translateZ causes a slight delay after changing the transform matrix while it re-renders the bitmap, and you see the switch - thanks for the advice
Choice between SVG and Canvas comes down to a balance between performance and interactivity, IMO. It is very easy to attach events and create interactions with a SVG object -- much harder to do that in Canvas (basically, you have to keep track of everything that was drawn). The flipside is, Canvas it effectively a bitmap, doesn't care what the pixels are, so the complexity is a constant regardless of what is drawn. SVG renderers will start to bog down once there are "too many" elements.
SVG hits a performance ceiling as number of elements increases. Canvas, since it's rasterized image can handle a rasterized representation of millions of SVG elements.
However as Canvas dimension increase, it will hit a performance ceiling.