Using removeChild to clear off a few in-game elements I noticed a bit of lag when testing on some devices so thought I’d better have a look at what the fastest removal methods are.
The three methods I selected to test were removeChild, display=”none” and a simple hide the element offscreen. Again, testing has been carried out at JSPerf.com.
My first test was on Chrome 16 and the results were pretty conclusive. display=”none” was very slow, and hide the element was by far the fastest – over 4 times faster than display=”none”.
So, conclusive proof – I should just hide my elements off the screen.
Err, no. I next tested Firefox 9.0.1. Ah, here removeChild was 2.5 times faster than both display=”none” and hiding the elements.
IE7.0 then. display=”none” and the hiding elements method were nearly 3 times faster than removeChild.
What about devices?
With Android 2.2 (Galaxy Tab 1) display=”none” was the fastest method, but only marginally so over the other two.
Safari on iPad #1 (4.2.1) flips the results on their head again with removeChild() being nearly 3 times quicker than the other two.
So how do we interpret this data? A chief decision to make would be what the target devices are. Then choose the quickest method. If we wanted a more generic approach then a series of conditionals would allow for all three methods to be present, using the most relevant one for the current browser.
For the prototypes I am working on, number one target is the iPad. A lot of my focus has been on trying to avoid using the Canvas element (entirely due to horrible performance on Android with it).
The (very simple) code used is here (for simplicity’s sake I use the inverse method as well to bring the element back onto the stage for subsequent removal):
var testDIV = document.createElement(‘div’);
testDIV.innerHTML = “Hello World”;function displayIsNone()
{
testDIV.style.display=”block”;
testDIV.style.display=”none”;
}function removeChild()
{
document.body.appendChild(testDIV);
document.body.removeChild(testDIV);
}function moveVideo()
{
testDIV.style.left=”10px”;
testDIV.style.left=”-9999px”;
}
Try the tests yourself here: http://jsperf.com/removing-an-element-from-the-screen/3.
This approach is massively dependant on what sort of game/interaction you’re creating, but based on the graphs above it seems that to me my approach would be to always hide off-screen and then run a removeChild sweep on all off-screen elements on a set interval / at known “low cpu” times. Sort of like your own garbage collection. Like I said it depends entirely on the situation, for example this approach wouldn’t work for say a nice particle burst as you need fast recycling going on. But for something slower / less intensive it should give a good trade-off.
Entirely agree. I’m building a game with many collectibles – I’ve gone with hide off-screen (but use as a pool) – then clear the screen at level end. I’ve certainly got my frame rate back to 60fps on my target devices after applying this method. Interesting to find out these ‘foibles’, but annoying that these simple actions aren’t trivial.
I guess fighting with the tech is an essential part of getting familiar with a new technology, but really I’d rather be concentrating on the job of making cool games.