iOS Performance Issue

I am facing some challenges in getting our game running properly on iPad. I have boiled it down to setting a mask on a container - regardless if you have any graphic elements or not. Below is a link to a CodePen. Running the pen on iPad gives about 8.5 frames per second. On most other devices this is ~60 and 33.3 on iPhone X.

The game is running in WebGL. Switching to canvas gives higher fps but there are too many rendering bugs in canvas mode for us to consider using that.

Any ideas on what and why would be very helpful.

Hi @Fredrik,
I can’t see the code: “Anonymous Pens can’t be embedded”

Oh, just click on the ‘Edit on CodePen’ button =)

Sorry @Fredrik, Codepen don’t let me see the code. I can enter in your codepen, but is in an infinity refresh loop.
In others pen I’m able to enter and edit.

Strange… I can open it in icognito mode as well on different computers. Here is the code from the pen if you want to try to paste it in. It is using the following js imports:

//cdn.jsdelivr.net/npm/phaser@3.15.1/dist/phaser.js
https://cdnjs.cloudflare.com/ajax/libs/fpsmeter/0.3.1/fpsmeter.js

    var config = {
    type: Phaser.WEBGL,
    width: 1920,
    height: 1080,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 200 }
        }
    },
   fps: { target: 60 },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var game = new Phaser.Game(config);


let fps = new FPSMeter();

function preload ()
{
    this.load.setBaseURL('https://labs.phaser.io');
    this.load.image('sky', 'assets/skies/space3.png');
    this.load.image('ball', 'assets/sprites/pangball.png');
}

function create ()
{
    this.add.image(400, 300, 'sky');
    
    let shape = this.add.graphics();
    shape.fillStyle(0xffffff, 0.6);
    shape.fillRect(100, 60, 500, 300);
    let mask = shape.createGeometryMask();
   
    for (let i = 0; i < 5; i++) {
     
    var logo = this.physics.add.image(
        Phaser.Math.Between(0,400), 
        Phaser.Math.Between(0,300), 'ball')
            .setScale(2)
            .setVelocity(100, 200)
            .setBounce(1, 1)
            .setCollideWorldBounds(true);

    let container = this.add.container(i, 0);
    container.add(logo);
  
    container.setMask(mask); // Removing this line restores performance on iPad
   }
}

function update () {
  fps.tick();
}

Uncheck Auto-Updating Preview in Pen Settings > Behavior.

In the end I got to enter, stoping the page loading (autoupdate was unchecked, the entire page was refreshing :thinking:).
I get 8fps in my old android with chrome.
Have you tried it on other ipad with the same browser?
Have you tried other browser?
First, I would check the webgl in your browser. You can visit http://webglreport.com/, or if you are using chrome chrome://gpu, and compare the report with the other devices.
Sometimes webgl for some reason is disabled, and need to be activated.

Thank you for testing it. I have tried on iPhone (high fps) and other browser on the same iPad (low fps). I will check on the site you provided tomorrow and compare to other devices to see if I can see anything there.

Just curious; did you try to remove the .setMask line and if so, what happened to the fps on your Android?

Just curious; did you try to remove the .setMask line and if so, what happened to the fps on your Android?

I get about 20fps. In this case, Chrome have disabled webgl2 because my android device (huawey y635) dont support it, and some webgl1 extensions are not available.

I see you are creating 5 containers, and to each container you add an image of a ball, then set the mask to the container.

As far as i know the current implementation of containers is not optimal, so if performance is an issue don’t use them. Phaser 3 promotes the use of a plain display list , all game objects sitting in the same display list and having the same parent. Containers have their own display list so that’s a probable cause for the performance lost.

Try doing the same thing without the containers, create the images in the scene, and then set the mask directly to the image. Hope it helps :slight_smile:

Yes, I tried to recreate the issue I was seeing as closely as possible and in the real game we need to use 5 containers. What is interesting is that even without the graphics (i.e. the balls in the pen) we still see really low fps numbers. So simply putting a mask on an empty container is detrimental to performance in this case. I am aware of that containers in general is stated to be bad performance, but I was surprised to see that even empty containers would bring down fps to a halt like this.

However, I configured the render to not use antialias and the framerate jumped from ~8 to 33.3 on my iPad. Very significant and within the acceptable range for me. This also worked in my original game where I went from ~3 to ~30 fps.

I think what I ran into has been device specific implementation of WebGL that has either been subpar or missing features/extension which lead to bad performance. Thank you jjcapellan for guiding me to webglreport.com that lead me in the right direction.

Here is the complete config with antialias turned off:

var config = {
    type: Phaser.WEBGL,
    width: 1920,
    height: 1080,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 200 }
        }
    },
   fps: { target: 60 },
   render: {
     antialias: false
   },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

Here is the updated CodePen in case someone wants to see and test it: https://codepen.io/anon/pen/aXzaZK

To add to the above; disabling antialiasing makes the graphics in the game look significantly worse. So we have now added a check and only disable antialias on mobile devices, i.e. sacrificing graphics for performance, which seems to be a fair enough trade-off at the moment. The degraded effect of no antialias is also harder to spot on a smaller screen.

Here my test with the android mentioned above :
1820x1080 antialias ----- > 8fps
1820x1080 ----- > 28fps
960x640 antialias ----- > 30fps
960x640 ----- > 60fps
480x360 antialias ----- > 60fps

If you look at the mobile resolution stats of 2018 and this results, it is reasonable to think that maybe 1920x1080 is not the best resolution for these devices. Although it depends on your specific case.
This game have a resolution of 360x480 (is using vectorial text):
https://jjcapellan.github.io/FlappyTours/

Thank you for testing it out. Yes, resolution seems to have a very high impact on the fps here indeed.

However, in regards the mobile resolutions the 640x360 is the reported screen size which does not take pixel density into account. A retina screen on iPhone has a pixel ratio (density) of 3 meaning that the true amount of pixel available on such a screen are 640*3 x 360*3 = 1920x1080. So to take advantage of the full resolution available one would have to scale up the game accordingly. At least this is my understanding of it =)

You’re right, I had not thought about that!! .:thinking:
In my case, scale up is almost mandatory.

what about temperature ? does your game increases it to very high temperatures or nor ?