sitelink1  
sitelink2  
sitelink3  
sitelink4 http://1 
extra_vars4 ko 
extra_vars5 http://www.isogenicengine.com/2010/11/08/update-top-10-javascript-performance-tips-android-iphone-engine-testing/ 
extra_vars6 sitelink1 

iPhone & Android Engine Testing

I’ve been very busy recently getting the engine to optimise based upon the device / browser being used on the client-side. Android on the Samsung Galaxy S is a very good performer and I understand that the 2.2 update to Froyo makes another good performance boost although I’ve not had a chance to try it yet.

I’ve found that the Android browser performs better with HTML based output rather than Canvas-based up to a point. The more HTML elements you push to the dom the more it slows down and eventually redraw speed becomes intrusively slow, however this is pretty much moot because of the offset created on the size of the graphics being displayed on the browser… let me explain…

The browser on a normal iPhone or Android device is much less powerful (in performance) than its desktop equivilent not because of the available features but by the available CPU and RAM specifications. This makes optimising for the devices quite important, however there is a pretty big silver-lining to the CPU and RAM cloud… screen size. Screens on these devices are quite small compared to your average desktop computer so the amount of stuff you can display on screen at any one time is reduced. There is also a need to increase the size of the graphics being used for a couple of reasons:

  1. The screens are small and small graphics on a small screen makes it impossible to see what is going on
  2. Interaction with small objects on a touch-based device is impossible so we need to make everything large enough to touch!

These two points work quite feverishly in our favour! Increasing the size of objects so they are clearly visible and easy to interact with means that we can display fewer on screen at once. This in turn means that we actually don’t need to worry so much about reduced CPU and RAM because the device doesn’t need to handle the vast amount of data that a desktop browser would display! Canvas is great when we want to push LOADS of stuff to the screen because you’re only holding on to one element in memory but because we’re not required to display huge amounts of stuff on a mobile device, HTML elements work out better.

If you want to speed up your canvas, the obvious choices are limiting what you need to redraw, reducing the complexity of any code within the game loop and handing off intensive tasks to separate worker processes where available. I have also found that by quickly hiding the canvas element, drawing to it and then showing it again I could speed things up a bit. This is because the browser isn’t having to update itself each time a new draw call is made to the canvas, since the canvas element is currently hidden. Once the redraw is complete the element is shown and the browser paints the screen only once. The same principal applies to HTML output.

Throwing constant appendChild calls to the DOM is very slow because the browser re-paints for each new element added. I found that updating the innerHTML with one large string of element data was the best way to push many HTML elements to the DOM ? a trick well known in the JavaScript programming community.

As many of you will know, optimisation is quite complex and very browser-specific. Apple has made an excellent mobile browser but I wish that workers were supported as handing off intensive calculations to a worker is a great way to increase the overall FPS of any game!

Tell us your experiences of mobile / cross-browser / cross-device development and share any tips & tricks you might have found along the way.

Here I am going to write down some of the things I have learned during my time as a JavaScript programmer… they are by no means secret and many other people before me have written them down, blogged about them and sung songs about them in their sleep… but hey, I want some kudos too :)

This stuff may be a bit dry and boring unless you are actively developing in JavaScript… but then again I suppose you wouldn’t be reading this unless you were, so without further ado…

Top 10 JavaScript Performance Tips

1. Don’t use “with”

Imagine your browser is like you pet, and “with” is like poking your pet it the eye. It’s not nice is it? So don’t do this:

var obj = {hello:1, goodbye:2};
 
with (obj) {
 
hello = 3;
 
}

Do this instead:

var obj = {hello:1, goodbye:2};
 
obj.hello = 3;

2. Math functions can be a bit slow… and Math.floor is a pretty well-used function!

So normally you’d do this:

var test = 1.2;
var testFloored = Math.floor(test);

But instead, this is faster on every browser except Chrome (fast enough that it’s worth using it as standard if you don’t want to do user agent testing because the Chrome speed is not significantly slower and the speed up is MUCH faster on other browsers):

var test = 1.2;
var testFloored = ~~(1 * test);

This technique also works if you want to do parseInt as it also takes strings so:

var test = "1.2";
var testFloored = ~~(1 * test);

3. Loops are fast but multiple statements are faster

Normal loop:

var i = 0;
for (var k = 1; k < 1000; k++) {
i++;
}

Multiple statements (yes, this is faster but looks terrible in the code… but if performance matters most, then this is the way forward):

i++; i++; i++; i++; i++; i++; ...

4. Counting down is faster than counting up

Normal loop:

for (var k = 0; k < 1000; k++) {
// Do something
}

Count down loop (faster):

var k = 1000;
 
while (k--) {
// Do something
}

5. Minimise lookup’s in loops

Instead of this:

for (var i = 0; i < anObjectOrArray.length; i++)

Do this:

for (var i = 0, n = anObjectOrArray.length; i < n; i++)

This works because instead of evaluating anObjectOrArray.length on every loop which means accessing the object and retrieving the length, the length is accessed once and stored in “n”, then “n” is evaluated against “i” each loop… which leads us on to…

6. Minimise access to object properties

Instead of this:

var obj = {data: {stuff: {moo: 1}}};
 
obj.data.stuff.moo = 1;
if (obj.data.stuff.moo > 0) {
alert(obj.data.stuff.moo);
}

Do this:

var obj = {data: {stuff: {moo: 1}}};
 
obj.data.stuff.moo = 1;
var tempMoo = obj.data.stuff.moo;
if (tempMoo > 0) {
alert(tempMoo);
}

This works because after setting the value for data.stuff.moo, there is no need to keep accessing the data object, then the stuff object just to access the moo value. Instead we store a local variable with moo’s value and this is quicker to evaluate.

7. Set variable values inside an if statement

Instead of this:

var moo = true;
var stuff = false;
 
if (moo) {
stuff = true;
}

Do this:

var moo = true;
var stuff = false;
 
if (moo && stuff = true) {}

You can also action the variable assignment on a false test with:

if (moo || stuff = true) {}

8. When writing code, ALWAYS declare your variables with an initial value

Instead of this:

n = true;

Do this:

var n = true;

(Unless you’ve already declared it earlier or you are accessing a global variable).

9. Use Duff’s device

I’m not gonna explain this one, there is a Wikipedia article on it here: http://en.wikipedia.org/wiki/Duff’s_device and if you’re still lost use the awesome new search engine called Google.

10. Learn JavaScript by reading the ECMAScript Spec

Learning to program JavaScript is pretty easy. Learning to program in JavaScript WELL is an artform, and the artform manual is the ECMAScript Spec… check it out: http://www.ecma-international.org/publications/standards/Ecma-262.htm

Hope this has helped someone! Remember if you have any performance tips… drop a comment!!