Performance issues with UI

I posted a few days ago on Github this issue, but I got very few feedback.
So I hope that posting it in the forum will catch more interest:

The short version of that post is that I’m cloning few 2D entities but Playcanvas takes several seconds on mobile to complete, making the UI experience a pain.

Here is a simplified repro project:

https://playcanvas.com/project/535478/overview/performance-issue

Just hit play and see the log.

So there are a few things in the Screen component and the Element component that haven’t yet been optimized and after profiling seem to be causing these issues in your project. The main culprit seems to be the syncDrawOrder function in the Screen component which recurses over all the children to update their draw order. If you use 1 Screen component then every time you add a new clone as a child this function is called again for all the children so that’s why it gets slower and slower on each addition.

So we can add some optimizations for this but in your case it won’t make much difference because of the way you are cloning all these tables. The way to make this faster would be to make sure that all the tables have been cloned and added just once under the Screen component. You can’t do it by using a script on each Table entity because that script will only be executed once that Entity is enabled. So you need a script that will clone all the tables while they are still disabled and that script will add all the clones to a disabled Entity. Then when everything is cloned add the disabled Entity as a child of the Screen - that way the syncDrawOrder method will only be executed once for all the children and not on every new table you add.

Hope that makes sense. We are also working on a different system for ordering draw calls which might make this method completely obsolete.

Thanks for your help.
I’ll try what you suggested.

Any eta on the new system?

We are currently working on it so hopefully soon. I don’t know yet if that will affect this specific issue but we’ll definitely look into that.

So before to change the code, I disabled the script on the Table that is cloning the seats, and I added all the seats statically inside the table.

This should simulate what you told, like clone everything before enabling the table container.
But the performance is worst. from 0.7 it goes to 0.9.

Instead, by adding a Screen component on the seat locations (the nodes that will contain the seats) it gains quite a bit of speed. I get around 0.32 seconds. (on mobile I went down to 2 seconds)

When you add a Screen component to each seat you are basically only calling syncDrawOrder on each sub-screen instead of a call on each child in the main Screen. You shouldn’t really use Screens like that - you should have one Screen and try to add everything under that screen in one go - so just 1 call to addChild to the Screen Entity for all tables and all seats, not one addChild per table.

Ok, so I created one group with 3 tables inside, already full of seats.
My script only clones this group and add it to the hierarchy once. No other cloning and addChild calls.
I also removed all the other Screen components.
It takes about 0.74 seconds.
I keep it like this in the project, in case you want to check.

Yeah there are still issues with the call to updateScreen - ultimately we need to not call syncDrawOrder like that for every child. I’ll create an issue on Github and will update you when we have a fix for this.

I would still try to use one Screen component instead of multiple because it’s just not really how this is meant to work and I’m not sure if you’re going to face issues down the line if you depend on that.

Make sure at least you’re only cloning tables at startup so any delay is just when the game is initialized. Sorry for the inconvenience!

1 Like

Yes I was planning to create a set of 3 tables on bootup and never delete it also while switching scenes. So the loading time could be a bit slower but will not effect the rest of the app.