Bad performance in Firefox (compared to Chrome based ones)

Hi everyone!

Short and concise question here; why is the performance so bad on Firefox and is there any tips and tricks to improve it?

I recently started testing my game project with firefox (still have a bit issues with it because of the webrtc connection but at least it renders now :laughing:)

On chrome, I get constant 120fps (120hz monitor). My goal has been to keeping the game fps maxed to my monitor without much stuff going on, since I am going to fill my game world with different sorts of stuff. But when testing the semi plain game world with Firefox, I get 80fps max. It is of course much worse on mobile devices which I haven’t really touched/optimized that much yet.

Furthermore, in Chrome I get 4.5ms per frame usually, and in Firefox it is… Minimum 12ms per frame. Currently there are two main parts that can be picked up from the graph:

  1. Animate (~1ms chrome, ~2ms firefox)
  2. RenderForCamera (~3ms chrome, ~10ms firefox)

This is pretty consistent with the frame budget I do have, which should be around 8.33ms. I have done a lot optimizations with Chrome and I am kind of saddened that the perf is what it is on Firefox. The semi empty scene I was talking previously consists of one character with animations, couple of simple assets and the game map, which is merged from smaller wall/floor pieces to like 8 meshes for each room I have.

The big questions:

  • Can anything be done to improve the frame time? (I should have hardware acceleration on already)
  • Will webgpu help?

Attachments:
Firefox graph:

Chrome graph:

Chrome is known to be faster than Firefox these days so I’m not surprised at this. WebGPU may improve things. You can try it out on Firefox’s nightly build. See Experimental features in Firefox - Mozilla | MDN.

2 Likes

Hello! Can you tell us a bit more about how your scene is set up? What kinds of elements do you have? Lots of meshes, particles, etc?

Some things that caught my eye on Firefox involve particles, like the very proeminent appendParticleVertex. This function is called 4 times instead of 1 if useInstancing is false: Babylon.js/particleSystem.ts at 209855cb589e59645f45596928d4243701f221f8 · BabylonJS/Babylon.js · GitHub, and useInstancing depends on knowing if the engine has support for instancedArrays: Babylon.js/particleSystem.ts at 209855cb589e59645f45596928d4243701f221f8 · BabylonJS/Babylon.js · GitHub, so you could check what these values return on Chrome and Firefox.

1 Like

Thank you both for replying!

Are there any perf improvements in the current nightly? Webgpu is pretty much out of question (for now) because of the changing specs. I get too many warnings and errors now to even try it for my game and no point fixing the issues beforehand since might be a huge timesink for nothing.

Sure!
The play area is a spaceship, that I build from individual mesh parts and merge them into rooms. Each room has a specific light source, so I can actually turn off/on the lights if the power goes out in the ship.
Here below is the minimum object list, without any extra objects. This will change in the future, since the ship rooms can be crafted with an editor and there will probably be like 20-30 rooms per ship. Each room also has a mesh for the top parts that are shaded black completely, and some hidden rooms as well (maintenance areas). And of course the rooms will be filled with furniture and other items. This is my main concern right now, since I want the empty rooms to be performant!
scene-1

Then there is the animated player character. There will of course be more of these if I add npc:s and since the game is multiplayer, there will be more players overall :smiley:
image

Then there are materials, which are pretty much materials that come from the glb files I use, or the node materials that I create from json files.

Then there are textures. I do currently use a texture map per room, meaning that each room tileset shares a 4096x4096 texture. That makes my life easier when I merge the room wall/floor pieces, since they all use same material/texture. Other than that, texture sizes are a lot smaller.

I use the default rendering pipeline and I have one highlight layer currently.

And finally; the particle system…

I currently have one particle system that was for testing if I could create cool looking skybox with particles and make an hyperspeed effect with that. After removing it, I get like 20fps perf boost in Firefox. But the framerate seems to vary a alot, like between 80-120…

Thanks for the explanation! So, another pretty salient point on the FF graph is computeWorldMatrix, which is part of the process of evaluating which meshes are visible from the camera. Since you said you have a lot of rooms, and I’m assuming these rooms are static objects, using freezeWorldMatrix could greatly help there: Optimizing Your Scene | Babylon.js Documentation (I’d check all of the tips in this page actually, they’re very helpful).

2 Likes

Actually this seems to work improving Firefox perf a lot! I think I’ve been hesitant to use this because I thought it can effect my “dynamic” lighting, but maybe it is ok? :smiley: Such a simple fix… I guess the problem is that the room meshes can be very complex 3d objects after the merge.

The fps seems to still fluctuate a lot more than it does on Chrome…
scene-2
I think one culprit might be the cascaded shadow generator that I use. There is one shadow generator for each of the rooms, since they all have a different directional light. The generator is initialized like so:

const shadowGenerator = new CascadedShadowGenerator(1024, directionalLight)
shadowGenerator.lambda = 0.5
shadowGenerator.filteringQuality = ShadowGenerator.QUALITY_LOW
shadowGenerator.shadowMaxZ = 40
shadowGenerator.numCascades = 2

Or it might be some random garbage collection? It is pretty hard to find out what the real bottleneck is :frowning:

Has someone updated the page or is there another one of these somewhere? This actually is really informative, but I think I haven’t read this one… Might be mistaken as well :smiley: Also off topic, but there is a small typo in:

The drawback is that this could look low rea.

Ok I just compared the inspector results in Chrome and Firefox and now I have some interesting questions. Take a look:

First of all, on Firefox it says that GPU frame time is 0, so it is not using the graphics card at all? But hardware acceleration should be enabled! I think this affects all the other metrics if it doesn’t use the acceleration? Can you see any other worrisome thing in this list?

Actually this seems to work improving Firefox perf a lot! I think I’ve been hesitant to use this because I thought it can effect my “dynamic” lighting, but maybe it is ok? :smiley: Such a simple fix… I guess the problem is that the room meshes can be very complex 3d objects after the merge.

No need to worry, it won’t affect lightning calculations as long as your objects don’t move (and even if they do, you could unfreeze them just for the update :stuck_out_tongue: ). It also won’t matter if the objects are complex after the merge or not.

The shadow generator might be a culprit, you could try disabling them and comparing the performance again? If you want another scene with them too you can try this one: Examples: Load glTF model | Babylon.js Playground (babylonjs.com). Testing this scene on my machine, I do see higher frame times with FF (Chrome/Edge gets to 12ms max, FF to 14-15ms).

Has someone updated the page or is there another one of these somewhere?

Hm there are some other sprinkled tidbits of performance advice on many doc pages, but this is the “general tips” page, I guess.

Oh, that’s because unfortunately Firefox doesn’t support some extensions we need to measure GPU time :frowning:

One small tip about your results, I can see that Chrome and FF have sligthly different resolutions. I don’t think it’s goint to make a huge difference here, but it’s good practice to always keep the same setup when comparing results :slight_smile: Given that, we can see some big differences in Meshes selection time (which freezeMatrix is a part of the optimization process), and Animations too. What kinds of animations do you have on the scene? Only the player character?

1 Like

Yeah I have pretty bad perf in the scene you provided on Firefox as well… But I think I have kind of tried everything to optimize it for the game scene I have. Since the game world is looked from the top angle (diablo/poe style), I can use the shadowMaxZ value to cut away the shadow rendering. At least I think it helps with perf? :smiley: Another thing I can do is to mark shadow casters as static. For instance, if I have a sofa/couch in the game world, it probably won’t move. And if it does, I can also unfreeze that as well. Same thing with the world matrix calculations.

It seems that something is sometimes hogging some frames a bit, see the next picture. That is pretty much one bad frame between the good ones, on Firefox.
scene-3

True, I was a bit lazy! :smiley:

The current initial scene just has the character animations, which play constantly (idle/walking/running). There will be a lot more animated objects in the future, for example npc models and some technical gadgets.

Can you share your capture on Firefox?

On the animations side, there’s one possible optim that is baked texture animations: Baked Texture Animations | Babylon.js Documentation (babylonjs.com), but they have some restrictions and they’re still slower on Firefox (but faster than regular animations)

Probably next time I have a performance session using Firefox… I think I will continue this endeavor a bit more then!

Yeah I remember these from back in the day. I think this is the “final” option if everything else fails, since there will be another complexity layer on top of the semi easy animation setup I have now. I will have a lot of animations in the future, especially for the character, so we will see I have to resort to this. Also a bit worried about the texture generation, since that seems to hog the browser/main thread until it has done its bidding…