All the benchmark information available at the time talked a lot about how innerHTML to create new objects was much faster than manipulating the DOM by hand in JavaScript. This makes sense. JavaScript is slow, but in most browsers, DOM objects are separated from JavaScript by heavy COM or XPCOM abstraction layers, so if you can minimize the number of DOM calls you make, that should make your JavaScript faster. Based on this reasoning, I initially wrote my scrolling code by erasing all my objects and creating replacements with a single innerHTML call. Unfortunately, this was really slow (too slow for most games), but I was too busy to work out a better approach.
I recently found some time to take a second look at this, and I found that the performance issues were more comlex than that. In fact, there is an overhead for manipulating the DOM, but it's actually not too bad. Creating (and to a lesser extent deleting) DOM objects involves a much larger overhead. Also strange is that IE8 is much slower than IE6 for a lot of this DOM manipulation (probably because it's properly synchronized etc.).
So the correct way to create a scrolling background is not to restrict oneself to a single DOM call. Instead, to scroll a bunch of images, it's fastest to go through each image and move each one by an appropriate amount (by using divElement.style.left = '?px'). It results in hundreds of DOM calls, but it's much faster than creating new images. I was thinking of creating some sort of complicated DOM hierarchy, so that I could move multiple images with a single DOM call, but that wasn't necessary--moving each image individually was sufficiently fast. Of course, you need to create new images and remove old ones as new areas come into view or move out of view, but the performance saved by creating fewer new HTML elements counteracts the cost of the extra DOM calls.
So some quicky benchmarks reveal that when 100 moves of around 25 tiles, 128x128 in size, in 5 pixel increments take this amount of time (in milliseconds) :
IE8 with innerHTML complete refresh of all objects | 14563 |
Chrome with innerHTML complete refresh of all objects | 5843 |
FF3.5 with innerHTML complete refresh of all objects | 10918 |
IE8 with simple move elements around | 1919 |
Chrome with simple move elements around | 605 |
FF3.5 with simple move elements around | 1691 |
IE8 with simple move elements and reusing old elements | 1641 |
This means that it's probably possible to do simple games in IE8, so there's no immediate need to switch to using canvas and restricting oneself to non-IE browsers. I'm hoping that developers won't program their HTML5 games using only the canvas element because I think more traditional methods are sufficiently fast and more compatible. In fact, if I do move to use HTML5 features, I'm vaguely thinking of going with SVG, but I'll have to see how the performance evolves.
No comments:
Post a Comment