drawImage performance on iOS vs CSS

I noticed something interesting earlier whilst trying to improve the performance of Dragons that I thought I should share. When I first considered how the game would look I settled on a full screen scene. I blogged how excited I was about this and that I could finally sit back and create full screen renderings in Photoshop. I’m using .png files for the backdrops. I tend to use that format for everything these days.

The theory was simple in that I would run through setLevel() once per level and set everything up. One of the things to set up is the current stage backdrop. For this I set the backgroundImage property of the canvas’ style to be whatever background I choose.
Something like this:

g.canvas.style.backgroundImage = “url(‘…’);”;

Very basic CSS stuff. g is my global namespace.
I figured that this would save me a hefty drawImage() call during the main game loop and therefore preserve some frame rate.
This was a poor assumption. At least on iOS. And even then it appears more so on iPhone 4.

I scratched my head as to why first gen iPod Touch could render the game at roughly 20FPS and iPhone 4 struggled along at around 6FPS.
So I played around with it a bit and took stuff out. I also killed shadows on text and cut back on the number of sprites on screen. None of it made a difference.

Meanwhile over on Android the game was flying along like a train.

I then decided to take a closer look at the “big” stuff. By big stuff I mean the operations that involve the most pixels. I use drawImage for everything so I reduced the size of the sprites and took out sprite scaling and rotation. No real difference was recorded. So I put it all back in.
I then took a look at the CSS call to paint the backgroundImage of the canvas in what I thought was a one-time-per-level operation that exists outside of the loop.
I stripped out the CSS bit and rendered the full screen scene on every game tick. To try and help it along a bit I also reduced the file size of the .png files from 43k to 3k. I also ignored diffusion since this doubles the file size even at 8bits.

I uploaded the new game code and assets and refreshed Safari on the iPhone4.

To my amazement the frame rate had more than doubled to (a still poor but more acceptable) 16-20FPS. Android was, to be frank, no different. It still motored on beautifully.

So the valuable lesson that I’ve learned here is that the best course of action on iPhone (at least it is right now before iOS5 arrives) is to do all full screen drawing with drawImage and not rely on CSS. Alternatively of course don’t do ANY full screen drawing.
One of the smoother games I’ve completed, Galactians, works against a plain black backdrop a la the arcade games of the early 1980s. Perhaps there’s something in this.

I’d love to hear some thoughts on this. I really am not a great coder so muddling through this stuff is often mesmerising at best. Be interesting to hear what other HTML5 game developers are doing to steal back some FPS.

%d bloggers like this: