3 ms·
If you want to draw a lot of data, you have to use canvas. If you want to have vector graphics, you have to use SVG. What are you supposed to do when you need b
by gruseom 13y ago
If you want to draw a lot of data, you have to use canvas. If you want to have vector graphics, you have to use SVG. What are you supposed to do when you need both? Good luck to you my friend
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.
- camus 13y agoDo you have a live exemple somewhere ? i'm curious about how well this technique performs.
- gruseom 13y agoNot at present, sorry.
- artumi-richard 13y ago> Could anyone add info here. 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:
- gruseom 13y agoOh good. I had nightmares of not being able to still do this. Care to describe the bugs and workarounds?
- artumi-richard 13y agoWe wanted the SVG to be responsive, but altering the size of the svg itself didn't work well in all browsers. So we put it in a div and resized that and told the svg to fill the div. We have had to set the height on the div otherwise it defaults to the native height of the svg in some browsers, rather than the resized height. The svg did maintain it's proportions however. 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...
- gruseom 13y agoThanks! I came back to add a belated comment and am very glad to see your answer. My belated comment is that I just upgraded that code to HTML5 and it works fine.
- spellboots 13y agoYou can use document fragments for this and get a similar performance boost without resorting to string concatenation.
- gruseom 13y agoDo you mean SVG document fragments? Can you explain in more detail or point to an example?
- spellboots 13y agoHere is an introduction. They are not SVG specific but you can build SVG elements in a document fragment, which is a lot faster than appending to the DOM, then append the fragment to the DOM all in one go. See http://ejohn.org/blog/dom-documentfragments/ 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.
- gruseom 13y agoSo these are regular document fragments? I vaguely remember that we tried that and it didn't work nearly as well, but it's been a while. Building strings and using innerHTML is a very ugly Ah. Then you'll be dismayed to hear we use tables for layout as well :)
- spellboots 13y agoIn fact, using a document fragment is actually faster at least in some cases: http://jsperf.com/svg-fragment-test http://jsperf.com/svg-fragment-test
- microcolonel 13y agoThe naiive approach was fastest for this example, but that's probably because the document was so small.
- underwater 13y agoYou should look into React. It has a similar approach (rerender everything) but handles the DOM construction and modification in an intelligent and performant way.
- spicyj 13y agoThere's even an (underdocumented so far) React library for drawing to either Canvas, SVG, or VML (using the same API): https://github.com/facebook/react-art https://github.com/facebook/react-art