I've created an HTML5 Canvas and JS game that runs great on a desktop or laptop in Chrome (30fps), but on mobile Safari I only get around 8 fps. Are there any simple tips or tricks to increase the framerate?

7 Answers
7

Unfortunately, the answer is to draw less. I've found the bottleneck with canvas based applications (on any platform, really) is the time it takes to actually draw pixels.

Here are some things to try:

Use several canvas layers. Draw your background to one layer while drawing your objects to another layer (absolutely positioned on top of the background layer). (Note: I haven't tried this on mobile safari, but it can help on other platforms)

Only redraw sprites that have changed. This is tricky but definitely increases performance. The idea is to store whether or not a sprite needs to be redrawn and redraw only sprites that need it along with the background behind them. (This also needs to cascade to other objects that sprite might be overlapping.)

The thing with developing on Chrome is that a) its JavaScript engine (V8) is fast as hell and b) the newest versions (7,8,9) all have some GPU acceleration when it comes to canvas rendering. That coupled with the fact that mobile hardware just isn't as powerful as your desktop/laptop means that it'll be really difficult to get anywhere near the same performance on mobile safari.

I think, for the time being, the best approach might be to target your game at mobile safari from the get go and try and build a game that's not as redraw intensive.

+1 Drawing less is definitely and unfortunately the way to go here, although with a second canvas for the background layer and a dirty flagged approach you can gain up to 50% more performance in some cases.
–
Ivo WetzelNov 8 '10 at 7:41

This is a bit of a long shot, but can your game operate on DIV sprites with CSS transforms instead? I say this because I'm getting some wonderful performance with moving things around on iOS devices with CSS transforms and transitions.

These appear to be properly hardware accelerated, with the bizarre caveat that you must use the 3D form for the transforms (i.e. translate3D, rather than translate) for the acceleration to kick in. It's really really buttery smooth, and the iOS browser implementation supports the form where you just set a 16 element float matrix directly, which is very convenient for me.

I'm so impressed with how smooth it ends up being, that I've been meaning to try a simple game project written this way.

I'd hate to add an answer to an old thread - but I'm surprised nobody mentioned this.

When you're writing your first games, just write them how you would expect them to work performance wise. The techniques above are good starting points to keeping performance high - but the real trick is the profiler. If you profile your application in Chrome or Firefox (hint: use lots of methods so you can see exact bottlenecks; so you don't have to move stuff later - you should be doing this anyway.), you get the added benefit of seeing exact timing results. In my case, I saw constantly redrawing the background took 80% of the browser time. After I moved that out of the way, I saw other calls taking up 40% and more respectively. After an hour or two, I saw a substantial FPS gain.

I would also like to hear from your results. I've been trying to do the same thing. I found that doing lots of math is fine but soon as you put a canvas in there its goes mental and frame rates fall.

I had an foreground overlay that displayed effects. It was a very high quality image but the alpha stuff slowed it down so much that I dropped it completely in return for more frames per second.

Another thing I did was to use PHP to work out some of the heavy maths. I had large datasets but rather than get JavaScript to compute and show the data, i decided to let PHP do the work and let JavaScript show results. This didn't save much time because JavaScript is "sehr gut " with maths.

I take it your whole site is in HTML5 so try playing with the background worker.