Missing drawing API: Canvas vs SVG paradox
bajcic.com
bajcic.com
We solved this problem for our domain by using SVG but bypassing the SVG DOM. Instead of making API calls to build up vector elements, we string together a gigantic blob of SVG markup as text and then splat it into the DOM in one go using innerHTML. This works surprisingly well—it's amazing how much computation you can cram in there without noticing any lag. We rebuild pretty much the entire UI on every mouse move and scroll.
At the time we came up with this trick, there was one big drawback: you couldn't put SVG elements inside HTML elements unless your doctype was XHTML. I believe that has changed with HTML5, but haven't ported that code yet. Can anyone add info here?
I have no idea how close this comes to Web/OpenGL; probably not very close, but it was a way out of the dilemma for us.
Edit: It used to puzzle me why this was so fast, but it seems obvious now. JS engines have optimized string concatentation, and the rendering of all that markup is happening on the C++ side, so both things that have to happen here are relatively quick. What's slow is the trip across the Grand Canyon from JS to the rendering engine, and this technique only does that once. Essentially, you're batching up all your API calls, and that saves you so much that the fact that you're using a horrifically inefficient text protocol to do it doesn't matter.
It works - desktop and mobile.
I have recently successfully used inline SVG in IE10, Firefox, Chrome and Safari. I had issues, and found bugs, but I also found workarounds fairly quickly.
I used the html5 doctype and the default Content-Type:
Care to describe the bugs and workarounds?
Also, we wanted to dome some simple onclick and onhover events on certain elements within the svg, and to do this we had to keep the <script></script> stuff outside the SVG because of safari. Interestingly having the javascript within the SVG worked well with the other browsers...
My belated comment is that I just upgraded that code to HTML5 and it works fine.
See http://ejohn.org/blog/dom-documentfragments/ or google for an introduction.
Building strings and using innerHTML is a very ugly way to get performance, you should definitely try to using the document fragment approach as it has similar performance characteristics.
Building strings and using innerHTML is a very ugly
Ah. Then you'll be dismayed to hear we use tables for layout as well :)
Ultimately if you want to draw truly giant giant data sets, you need WebGL. What's missing isn't a new browser drawing API, but a good WebGL charting library.
But speaking of it, canvas has a sort of a bad api design and its not very optimized for GPU, you know..
beginRender()
...
swapBuffers()
endRender()
Since Adobe is now on the HTML side of things, I wonder if they could propose a good api, or at least try to make a optimized api version of the canvas.. as this is definetly their domain..
Also i remember to see a proposal for a more mature path api from that guy behind Gallium, Years ago .. Zac Riusin(or something) that looked promissing..
https://github.com/sebmarkbage/art
Essentially, you write your drawing code once and it can render to Canvas, SVG, or VML depending on what you need. It doesn't yet have great documentation or a ton of examples, but it's in use at Facebook in their ads management and the page insights interface.
There's even bindings to Facebook's React (http://facebook.github.io/react/) drawing library which is a declarative library for building efficient, reusable view components: https://github.com/facebook/react-art. I haven't had a chance to play around too much yet but it looks very promising.
I agree that it's annoying that you have to think about it, but since it's a low-level drawing API, I understand why it's done that way.
Since the web is predominantly HTML, Chrome and other browser devs have focused all their efforts on optimizing it (and JS).
SVG and Canvas rendering has not gotten that kind of attention. However it sounds like they are working on it now.
The upshot is that even if it doesn't seem like it would work today doesn't mean it's dead in the water and we need yet another drawing API. Give it time.
It also means -- and I know this sounds crazy -- that you could try drawing your dots with absolutely positioned 1px by 1px DIVs. I know this sounds absurd but I once worked on a scrolling + scaling timeline widget that performed 10x better when implemented with absolutely positioned HTML DIVs than in SVG.
(And like gruesom noted, it is probably best to blast all your DIVs the DOM in one shot.)
I think that comments like this confirm that we really need new/better APIs, and i hope that browsers will get into it.
And 40k elements is a no way with any method other than canvas on Firefox, though it can sometimes stay somewhat usable with SVG on Chromium.
I've been trying to develop a toy genome browser as a pet project while procrastinating on writing my thesis. I faced a similar problem when rendering a genome feature density plot and found mouse interactions with it was painfully slow. I solved it by rendering the svg with d3 and then use canvg.js to convert the svg into canvas. You can see the toy example here: http://www.nextgenetics.net/tools/browser/browser.html
This prototype shows all genes from human chromosome 1. You can use WASD to scroll and Q/E to zoom in and out. The white density plot on the bottom is d3 made and converted into canvas with canvg. All svg are rendered with d3 using an element pooling system.
I really liked the object model of paper.js, but the very same layers/object model led to some performance issues ol large data sets. So im stuck with custom canvas implementation with no vector/high res export solution.
Have a look at this fiddle:
http://jsfiddle.net/theo/9narA/
25,000 3D cubes - with the required 8 vertices and 6 faces - each gently rotating around its X-axis in real time. Use your pointing device to pan, zoom and rotate the display.
Built with the Three.js library. Requires fast machine with good GPU and browser that supports WebGL.
What is funny is the author of Three.js did exactly the same demo ( without the cheesy music ) with his framework, the difference is he has an real framework used by thousand of developpers and he did not need 2 million dollar funding to create it.
Also there is one funcionality you want there: type in gene name (or prefix) and highlight matches and fade out rest of them to lets say 0.05 alpha.