title: Efficient realtime SVG entity management with javascript
body: <p>[edit]sigh... the "spam protection" here isn't letting me post the links, so I guess it's URIs instead[/edit]
  [edit2]ok, BROKEN forms of the URI that can get past the regexp...[/edit2]</p>
  
  <p>I'll preface this by saying I'm totally new to SVG, and somewhat new to Javascript, having come from a background in low-level C. On a whim, though, I decided to try my hand at writing a realtime game using all these fun new web technologies.</p>
  
  <p>I'm fully prepared for the answer to be "The web can't do that yet, sorry!" This may simply be too much data throughput for a browser.</p>
  
  <p>So I have written the beginnings of an Asteroids clone. It is a thin SVG document, with the entire game being dynamically generated as SVG line/polygon entities from javascript. Much to my surprise, this actually worked. I was able to get <em>mostly</em> smooth animation from Firefox 3.5 (not tested on anything else).</p>
  
  <ul>
  <li><a href="http://public.codenazi.fastmail.fm/asteroids_dynamic.svg" rel="nofollow noreferrer">original, as-needed allocation version</a></li>
  <li>(javascript) http - public.codenazi.fastmail.fm/asteroids_dynamic.js</li>
  </ul>
  
  <p>This does variations of this each time a rock it hit:</p>
  
  <pre><code>// on startup
  svg_ns = 'http://www.w3.org/2000/svg';
  container = svgdoc.getElementById('rocks');
  
  // each time a rock breaks, times ~20
  x = svgdoc.createElementNS(svg_ns, "polygon");
  x.setAttribute(...various things...);
  container.appendChild(x);
  </code></pre>
  
  <p>Unfortunately, it's not smooth enough. It lags all the time. There are jerks and breaks in the flow, even on my modern 3GHz box. Several friends I have shown it to also immediately complained of stuttering.</p>
  
  <p>I have spent the last week or so reading up on how to optimize javascript, which helped slightly, but I suspect that the issue is all of the insertions/deletions I am doing to the DOM for pretty much every action in the game. I have considered various pre-allocation schemes, and don't really want some complicated memory manager if it's not actually going to help.</p>
  
  <p>What did come up a lot in my research is discussions of "reflow" and "repaint". As I understand it, any insertion/deletion to the DOM will cause some sort of re-parse of the entire tree, which is slow. The common solution was to collect sub-nodes together first, and only do a single insert into the actual document. This model doesn't really work with a game like this, though.</p>
  
  <p>As a test, I sort of combined the two ideas: pre-allocate when possible, and insert in groups when possible. So in this version, each asteroid is replaced with a  SVG group, and the asteroid, it explosion effects, and its pop-up score are created all at once. This way, allocations and insertions only happen when asteroids are created (not destroyed). To keep these extra effects hidden until they are needed, I set the "display: hidden" attribute.</p>
  
  <ul>
  <li>new, group-preallocated version:  http - public.codenazi.fastmail.fm/asteroids_prealloc.svg</li>
  <li>(javascript):  http - public.codenazi.fastmail.fm/asteroids_prealloc.js</li>
  </ul>
  
  <p>When the rocks are <em>created</em>, this happens instead:</p>
  
  <pre><code>g = svgdoc.createElementNS(svg_ns, "g");
  // make the rock itself
  rock = svgdoc.createElementNS(svg_ns, "polygon");
  rock.setAttribute(...various things...);
  g.appendChild(rock);
  // make the destroy effect (repeated many times)
  frag = svgdoc.createElementNS(svg_ns, "line");
  frag.setAttribute(...various things...);
  frag.style.display = 'none';
  g.appendChild(frag);
  // actually add it
  container.appendChild(g);
  
  // then, sometime later when a hit is detected
  rock.style.display = 'none';
  frag.style.display = 'block';
  </code></pre>
  
  <p>I think this DID make it a bit smoother! But... it also dropped the framerate significantly. I have to keep track of more elements at once, and some testing has shown that wrapping everything in another  element makes the SVG render slower as well.</p>
  
  <p>So my question is this: is this even possible? Can I actually get a reasonably smooth SVG animation like this out of firefox? Or is firefox inherently going to have stalls/stutters? If it is possible, is there some memory/element management technique that can allocate/insert SVG elements in a better way than I currently am?</p>
  
  <p>I kind of suspect that the answer will be to just stick with the first, easier method with fewer elements and wait for the future when browsers are better... -sigh-</p>