Hacker News new | ask | show | jobs
by Lockal 1078 days ago
But SVG is slower than Canvas. The main use case for sparklines is embedding them into cells, many hundreds or even thousands of them [1]. With hundreds of SVG files page becomes becomes visibly slower (first paint, scroll, interactions). I suggest to invest some time and check canvas solution too.

[1]: https://www.google.com/search?q=sparkline&tbm=isch

8 comments

If pure client-side performance is key, and you can afford a little extra bandwidth, then go a little further and pre-draw server-side and transfer as date:uri images. Then you are not relying on JS running on the client to draw on the canvases. Not an option if you need things drawn more dynamically client-side, in response to user changes/filters/etc without a server round-trip, of course.

Though in any case if you have thousands of sparklines in cells I'd question if the display is actually useful to anyone.

Unless it is a large table of data you are presenting in which case thousands of rows has display time issues in my experience anyway. I have in mind a CSV preview on one of our support dashboards which takes a noticeable time to render when given a client import of ~8,000 rows and ~15 columns and that is not a lot more than a plain HTML table.

This is only an issue on chrome-based browsers; performance in Firefox is much closer to what you would expect. You can/could (late 2022) reliably crash chrome by displaying 1000+ unique SVG files on one page, with each SVG simply displaying a single line of text. My current workaround is rendering the SVGs to png serverside if the client is chrome-based, as canvas feels like the wrong solution.
Since the vast majority of users are a chromium based browser, doesn't this put the burden on your server pretty much all of the time? why even bother with code to do 2 different things when the other thing is such a niche segment of users?
This kind of thinking is how we ended up with the IE6 disaster.
That's my point of having the logic to do multiple workflows based on browser type.
True; so the server-side rendering is tuned for minimal server load, with the resulting output being heavily degraded. Still good enough for its purpose, and Firefox gets the bonus hi-res thumbnails :-)
Of course SVG is slower than Canvas. SVG is fundamentally much more powerful. Canvas is just a pixel buffer. You know what's even faster than Canvas? JPEG.

Of course these tools have different use cases. Handling scaling events and interactivity with Canvas is far, far more laborious.

The great thing about SVG (and to a lesser extent JPEGs) is that you can produce them anywhere, not just in a browser with a JavaScript VM.

> You know what's even faster than Canvas? JPEG

Is that true? Isn't canvas a bitmap whereas JPEG requires decoding?

What's the fastest way to deliver the bitmap to the canvas?
Hardcode the RGB array?
So, BMP?
I find it hard to imagine a use-case for thousands of sparklines on screen at the same time! And if it’s not on screen, you don’t need to render it.

Instead of using svg files, just include them in the html, and make them simple. Each svg sparkline only needs to be two elements (the <svg> tag and one <path>), which is crazy efficient.

Canvas uses one element, instead of two, but you have to create a custom implementation of path rendering and do all that work in JavaScript instead of native browser APIs.

Canvas pulls ahead with drawing complex images where you have a single pixel buffer representing thousands of individual “shapes” because the DOM itself is optimized for interaction, not just drawing pixels, but I think that’s a different use-case from sparklines.

A spreadsheet with numerous sparklines per row would get you there.
There's an open source project I was briefly involved in called SSVG [1] that renders the SVG as Canvas to speed it up drastically, especially on Chrome. It works as a simple one-line js drop in for many common visualization examples [2].

[1] https://ssvg.io/ [2] https://ssvg.io/examples

In that case, browsers should optimize SVG more.
SVG could never be as fast as canvas.
SVG is a series of drawing commands (with transformations, filters, and so on). Which is exactly what canvas is. With appropriate layer caching of course it can be 100% as fast if the rudiments are similar and in the same context[1], and on many platforms it is. Chromium derivatives have a particularly slow implementation of SVG and it has tainted the whole realm.

[1] Obviously if you're zooming and transforming and animating layers there is going to be a cost, but that should be compared with doing the same with a canvas.

Canvas is just a pixel buffer. Even with sufficient caching SVG would be slower because there’s more work to do with parsing, etc.
Canvas is a pixel buffer...and a set of drawing rudiments to imperatively actually make that pixel buffer useful. If you were actually just using canvas as a pixel buffer it would be catastrophically slow.

SVG is a pixel buffer and a set of drawing rudiments to imperatively or declaratively actually make that pixel buffer useful.

The distinction you are drawing between these is sophistry.

SVG is a pixel buffer the same way html is a pixel buffer. It can have multiple types of animations, hover states, etc.
No the distinction is important and directly related to performance. Supporting the canvas API requires fewer CPU instructions to get to pixels on the screen. The browser has to do a lot more work to turn SVG into pixels
Hard to imagine that pure-HTML SVG is really slower than Canvas which relies on JS..
It is, it is! SVG is DOM, with event handling on every node, with attempts to apply CSS rules. Canvas for non-interactive charts is just "draw once and forget". It is a sequence of moveTo + lineTo, then you have a bitmap and nothing else. Extremely basic graphics, modern JS engines will handle it in the blink of an eye.

I don't even mention the fact that article suggests to return each SVG sparkline in a separate request.

Guess it depends on your definition of performance.
Ah, but Canvas does not rely on JS. You would update it using JS, yes. When you don’t update it, it’s just another image. Browsers are quite good at images.

In the end, I think it’s down to the complexity of the graph and the dimensions (in pixels, because images need memory, too).

How do you draw an image on a canvas without JS?
You don’t. My point is: After drawing, the canvas is “inert”. Rendering to the canvas once is probably more or less as expensive as rendering the SVG once. However, the SVG will probably be rendered a lot more than once. The page developer cannot control it either, the browser decides what’s best.
Canvas is faster _because_ it relies on JS. It’s a much dumber and stateful API - the browser has to do much less work.
Especially if we're talking using "many hundreds or even thousands of them" on a page.
> The main use case for sparklines is embedding them into cells

Says who? Citation?