Interpolated Penguin

Networking, coding, penguins, and some more computer stuff.

Improving Performance with Phaser.js

Through experimenting and talking with a bunch of people I have found a few ways to improve performance of Phaser.js.

Canvas vs Webgl

So you've start on your game, a little unsure of yourself but still pretty motivated. You've gotten a few good ideas, made some art, stitch stuff together and start testing! Aaaaand then you find out you only get 40FPS on Chrome and 20FPS on Firefox! Dang.

In a game that I'm currently working on I ran into this exact issue. In Google Chrome it would be decently smooth at ~60FPS but with massive stuttering. Firefox was much worse off at ~20FPS.

My game isn't crazy at all, here is a quick screenshot:
Screenshot of the game

Let's see if we can work on this. Talking with Rich I find out that Phaser.AUTO is often bad for performance. In fact Phaser.Canvas often performs much better, at least until browsers work out more optimizations for WebGL. I've since found a great article made by Burak Kanber Tuning PhaserJS Performance who goes into this issue with much more detail.

I tried Phaser.Canvas and got the following results:

Chrome Firefox
Phaser.AUTO ~60fps (with stuttering) ~20fps
Phaser.CANVAS ~60fps ~50fps (or better)

That's definitely an huge improvement! Again my game isn't crazy, there aren't tons of tiles or effects. For a 2D game I expect 60FPS.

Loading the Tilemap

You've worked out a wonderful workflow! You design your tiles, go over to your tile editor, place a few, reload your game and BAM wonderful level! You decide to have multiple layers, including one called floor, and everything on the floor is solid.

I first wrote a little helper function. This function allows for easy debugging of how long code takes to execute. Just call the function before and after what you are trying to measure.

static startTime: number = 0;

static debugTimer(){  
    if(Utils.startTime == 0 ){
        Utils.startTime = performance.now();
    }else{
        console.log(performance.now() - Utils.startTime);
        Utils.startTime = 0;
    }
}

Using this method I found a bit of an outlier with execution times. A little while ago I did map.setCollisionBetween(0, 10000, true, "Floor");. It was just a quick and dirty was to make every ID on that layer solid. I must have been making a bunch of changes when I did this, as I never noticed the increased loading time from it. Turns out it was taking 2879ms to run....

Replacing that with map.setCollisionByExclusion([], true, "Floor"); improved the loading times drastically.

Between2879ms
Exclude186ms

Burak has an article on this too: Optimizing PhaserJS for Giant Maps with Lots of Collisions. I really wish I had found his arcticles before finding this all on my own.

Debug

I don't actually have many numbers for this one (currently) but I've found that Firefox seems to spend a lot of time drawing the debug information.

Console.log()

Don't do this inside large loops. It takes a TON OF TIME to log things to the console. This can bring your game to a crawl very fast.