a simple benchmark intending to show slow SVG in Chrome and FireFox

88 views
Skip to first unread message

Stephen Bannasch

unread,
Oct 18, 2011, 7:10:40 PM10/18/11
to cc-dev...@googlegroups.com
I created an SVG Path Benchmark example (doesn't use D3) that measures the incremental time to draw a path that ends up with
5000 line segments:

http://bl.ocks.org/1296930

I was expecting to find Safari the fastest, Chrome the slowest, and FireFox just a bit quicker than Chrome because this is what
I find if I render a graph with D3 in the avalanche-js model:

http://stepheneb.github.com/avalanche2d-js/avalanche2d.html

I was hoping to have a simple test case for creating a performance issue for Chrome and FireFox ... but ...

this is what I measure as the time to add line segments 4750..5000:

Safari v5.1.1 (6534.51.22) 77ms
Chrome v14.0.835.186 86ms
FireFox 7.0.1 3407ms

I must be doing something wrong ... FF is not that slow ...

One clue is that I am using requestAnimFrame to schedule the work ... but the SVG path and the results rows in the table don't
appear until after everything is finished -- so I'm probably using it wrong.

ref: http://paulirish.com/2011/requestanimationframe-for-smart-animating/

fyi: You won't see the table results in the latest Chrome Canary because of this recent bug:

Regression: SVG in IFrame uses maximum height of container instead of specified dimensions.
http://code.google.com/p/chromium/issues/detail?id=98951


--
- Stephen Bannasch
Concord Consortium, http://www.concord.org

Stephen Bannasch

unread,
Oct 18, 2011, 11:08:09 PM10/18/11
to cc-dev...@googlegroups.com
At 7:10 PM -0400 10/18/11, Stephen Bannasch wrote:
>I created an SVG Path Benchmark example (doesn't use D3) that measures the incremental time to drawa path that ends up with 5000 line segments:
>
> http://bl.ocks.org/1296930

Here's the equivalent benchmark for drawing a line consisting of 5000 separate segments into an HTML5 Canvas -- it's about 40x faster than drawing with SVG.

http://bl.ocks.org/1297383

I knew drawing with an HTML5 Canvas was faster but didn't realize it was this much faster than SVG.

Chad Dorsey

unread,
Oct 19, 2011, 8:49:07 AM10/19/11
to cc-dev...@googlegroups.com
That's been the word on the street for a while, as I understand. No matter how you cut SVG, the objects are all individual DOM objects. Any change that is made needs to traverse the entire tree to update. Even clever approaches can't get away from the fundamentals of that problem, as I understand it. Of course, if things are in canvas, you have to deal with mouse interaction on your own, but things are beginning to croP up to help with that finally.

—Chad
>
> --
> ----
> post message :cc-dev...@googlegroups.com
> unsubscribe: cc-developer...@googlegroups.com
> more options: http://groups.google.com/group/cc-developers?hl=en
>

Paul Horwitz

unread,
Oct 19, 2011, 9:57:51 AM10/19/11
to cc-dev...@googlegroups.com
I don't see how you can interact with the individual graphic objects (the line segments in this example) if you don't have something like a DOM architecture behind them. But of course you don't have to interact with them for all applications, so it would seem that you ought to be able to turn that feature off and just treat the entire structure (the 5000 segments) as a single object if you're sure that you don't need to "see" the individual components (the segments themselves). Is that what HTML 5.0 does?

Paul (just curious -- there really is quite a difference between these two benchmarks!)
--
Dr. Paul Horwitz
The Concord Consortium
25 Love Lane
Concord, MA  01742
978-405-3223

Chad Dorsey

unread,
Oct 19, 2011, 11:24:20 AM10/19/11
to cc-dev...@googlegroups.com
There are frameworks (such as Easel.js) tackling this now.

—Chad

Stephen Bannasch

unread,
Oct 19, 2011, 11:28:22 AM10/19/11
to cc-dev...@googlegroups.com
At 9:57 AM -0400 10/19/11, Paul Horwitz wrote:
>I don't see how you can interact with the individual graphic objects (the line segments in this example) if you don't have something like a DOM architecture behind them.

You can't ... so if you need interaction you need to create an associated scenegraph framework in JavaScript to manage this. While you have to do the work yourself when you are using Canvas you have the choice from doing something very simple to whatever complexity you want.

I think faster is always better which is not the same thing as saying the faster technology is always better.

I'm having a great time using the D3.js framework (http://mbostock.github.com/d3/) which is powerfully integrated with SVG.

I think there number of places where SVG is a better solution than Canvas (ex: SVGEdit).

Another great thing about SVG is that because the result of rendering and interaction is expressed into a dom structure youcan write tests that can run outside the browser. D3.js has over 1800 tests and they all run in nodejs and take about 3s tocomplete. To me being able to write extensive behavior tests and run them this fast is also a disruptive performance increase.

However when the more primitive technology (Canvas) is 40x faster than SVG drawing large real-time sets of data and the slowness has a negative affect on user experience there's a great deal of computational headroom for re-implementing simpler scenegraph frameworks in JavaScript that supplement the Canvas object.

>But of course you don't have to interact with them for all applications, so it would seem that you ought to be able to turn that feature off and just treat the entire structure (the 5000 segments) as a single object if you're sure that you don't need to"see" the individual components (the segments themselves).

My current use case is to be able to draw a graph of real-time data quickly. Doing this with SVG becomes unacceptably slow whenthe length of the dataset is large (5000) and the rate of new data points being generated is 25/s or faster.

I also want to have reasonable performance on slower systems like iPads, Android tables or smartphones.

Of course there's nothing that prevents combining SVG and Canvas together. In the avalanche-js demo I could overlay a transparent canvas object over the inner portion of the DS.js graph (which uses SVG) and plot using Canvas while collecting data. I could still rescale the axes by dragging the D3 generated SVG axes while plotting and still replot the entire 5000 point dataset using Canvas in about 30ms.

I created the simple benchmarks because I wanted to understand just how big the difference was and at least create a simpleexample I could add to the bug trackers for Chrome and FireFox as an SVG performance bug.

>Is that what HTML 5.0 does?

Newer browsers have added some features that make it easier to write scenegraph-like functionality while using canvas. See my discussion of ctx.isPointInPath() below.

What Canvas allows is the capability to create or use associated scenegraph frameworks written in JavaScript of varying levels of complexity. With SVG you have a great deal of power ... but you always have the performance cost that power comes with.

The simplest version of a Canvas scenegraph would be to use JavaScript to erase the canvas and redraw the updated state of the visualization with every frame. Of course if Canvas was just 2x faster than SVG this would be silly.

There are many different JavaScript frameworks available that add interesting feature sets that work with Canvas.

A very simple example is Smoothie Charts (http://smoothiecharts.org/) which is a simple plotting library for realtime data thatscrolls the charts smoothly.

EaslJS http://easeljs.com/examples/sparkles.html implements a Flash-like API for rendering into and interacting with Canvas. Example: http://easeljs.com/examples/barGraph.html

Unveil.js http://github.com/michael/unveil by Michael Aufreiter takes an interesting approach to data visualization by creatinga rich Collections API for modeling the data. Data modeled with Unveil Collections can be rendered using Unveil visualization classes or other rendering systems like Protovis, Processing.js, or Scene.js.

Examples: http://dejavis.org/scatterplot
http://dejavis.org/linechart
http://dejavis.org/stacks

There are some improvements in the Canvas object in more modern browsers that make adding interactivity easier.

At one point at CC we wanted to write some tests for link-lines in MySystem which at that point used a canvas-based visualization. Thios isn't obvious how to do this -- do we compare the whole rendered image to a correct image -- that would be a mess.

I thought about a technique I saw used and described in the unveil.js data visualization library where objects which are rendered to a canvas have a checkActive method. This method "draws" a version of the object into the context *without rendering it* and then finds out if the clicked point is within that object using the ctx.isPointInPath function.

See Michael Aufreiter's explanation here: https://github.com/michael/unveil/blob/master/index.ndg#L475

ctx.isPointInPath() is supported in: Chrome 5+, Safari 4+, Firefox 3.5+, IE9 and Opera10

If you know an X, Y location in the canvas where only objectA should be drawn you could use this method to check if any other object was drawn there also.

See the isPointInPath function specification here:

http://www.whatwg.org/specs/web-apps/current-work/#complex-shapes-(paths)

The isPointInPath(x, y) method must return true if the point given by the x and y
coordinates passed to the method, when treated as coordinates in the canvas
coordinate space unaffected by the current transformation, is inside the current path
as determined by the non-zero winding number rule; and must return false otherwise.
Points on the path itself are considered to be inside the path. If either of the
arguments is infinite or NaN, then the method must return false.

Stephen Bannasch

unread,
Oct 19, 2011, 12:00:40 PM10/19/11
to cc-dev...@googlegroups.com
two link corrections

At 10:58 AM -0400 10/19/11, Stephen Bannasch wrote:
>EaslJS http://easeljs.com/examples/sparkles.html implements a Flash-like API for rendering into andinteracting with Canvas. Example: http://easeljs.com/examples/barGraph.html

EaslJS: http://easeljs.com

>See the isPointInPath function specification here:
>
> http://www.whatwg.org/specs/web-apps/current-work/#complex-shapes-(paths)

The link above is to a VERY large single-page html document.

This page is easier to load and read: http://dev.w3.org/html5/2dcontext/#complex-shapes-paths

Stephen Bannasch

unread,
Oct 19, 2011, 12:17:42 PM10/19/11
to cc-dev...@googlegroups.com
At 11:24 AM -0400 10/19/11, Chad Dorsey wrote:
>There are frameworks (such as Easel.js) tackling this now.

I looked at all the EaslJS 8 examples linked from this page: http://easeljs.com/

I think many of them would be easier to write and perform better using D3.js which uses SVG.

D3 Examples: http://mbostock.github.com/d3/ex/

Is there an app you know of using Easl.js that really shows it's benefits?

So far the main places where I think Canvas is better are:

- heatmaps (think the avalanche display of folders on all the desks or the temperature distribution in energy2D).

- real-time graphing

Chad Dorsey

unread,
Oct 19, 2011, 1:13:06 PM10/19/11
to cc-dev...@googlegroups.com


On Wednesday, October 19, 2011, Stephen Bannasch <stephen....@deanbrook.org> wrote:
> Is there an app you know of using Easl.js that really shows it's benefits?

The core example of Easel.js is the HTML5 game Pirates Love Daisies, for which it was created, I believe. Impressive in its right, though quite different in many ways, too.

Pirateslovedaisies.com

—Chad


>
> So far the main places where I think Canvas is better are:
>
> - heatmaps (think the avalanche display of folders on all the desks or the temperature distribution in energy2D).
>
> - real-time graphing
>
Reply all
Reply to author
Forward
0 new messages