Slate + style = performance drop ?

Hi,

I have added styles to my code in order to clean it and noticed a severe performance drop.

Everything was smooth and fluid when the options were in the code in each widget.

Without any other modification, i went for the style option and the game running behind the interface is noticeably slower now.

My interface can be quite heavy (dynamic arrays of lines containing buttons in scroll boxes, everything being transparent), but it doesn’t look like anything that could put a modern computer on its knees, and it was very fluid without the styles with exactly the same display.

Well, i am not really waiting for a short term solution, but i just wanted you guys to be aware of that, in case you haven’t tested heavy UIs.

Or maybe there are some good practices that i should be aware of ?

UE4 is fantastic by the way :slight_smile:

All the best

Cedric

Hi,

I just discovered the stat function in the console, so i can be more precise.

In the first screenshot, all my widgets are collapsed. You can see a fps around 100.

Second screenshot, the main menu widget is on, that makes 6 buttons, and already the fps drops to 40.

Then, third screenshot, i switch everything on, and the fps falls to 5.

My UI, even unfinished, is quite heavy, i would expect a slight drop, but from 100 to 5 ? And even from 100 to 40 with 6 buttons ?

Maybe i am doing something wrong ?
I have been following this tutorial:

Any advice welcomed, as my UI is supposed to contain much more things, which obviously can’t be done the way i currently do it.

Thanks

Cedric

Hi,

The interface is now almost finished and i can get refresh times of about 10s (yes, seconds, not milliseconds). Currently unusable.

It can display tens (maybe around a hundred) elements, but it is still nothing compared to what the editor can do, and the editor runs very smooth.

So it is obvious that i am doing things entirely wrong, probably from the start.

I am using a lot of nesting (elements in elements in elements…, like textblock inside horizontalbox inside verticalbox inside scrollbox inside compoundwidget inside verticalbox inside horizontalbox inside overlay…).

Maybe that’s not how it should be done ? Then how should it ?

It would be really nice to have a good practice sheet about slate and styles.

Thanks

Cedric

I’ve never noticed such a drop and I use quite heavy UI also so I guess you must be doing something wrong.

Could you paste your widget initialization code and maybe check if same things happen if you just add 1 button or any other custom widget to your UI?

Hi,

Thanks a lot for your answer, and sorry for this awfully long following wall.

First to answer your question, yes, i have a widget which is a event journal, where events are added one by one.
Each event is a new STextBlock added to the journal widget, which is mainly a SVerticalBox in a SScrollBox, so i am adding widgets one by one during runtime.
The first ones are displayed immediately, and after 10 or 15 events, they take about 10 seconds to display.

All widgets are inside a mother widget which divides the screen in 3 columns, each column containing many widgets that may be visible or not during the game.
Each of those widgets contains many elements, sometimes added proceduraly.

All the daughters widgets belong to the same custom class SYagWindow which is a SCompoundWidget mainly containing a title, a close button, and a container which is called YagWindowContainer.

Then all the window-widgets are filled in the hud.cpp file in the PostInitializeComponents function, after the initialisation of the mother widget:

YagHUD.cpp:

void AYagHUD::PostInitializeComponents()
{
	Super::PostInitializeComponents();
	
	if (GEngine && GEngine->GameViewport)
	{
		// get viewport
		UGameViewportClient* Viewport = GEngine->GameViewport;

		// mother widget that contains everything
		SAssignNew(YagHUDWidget, SYagHUDWidget)
			.YagHUD(TWeakObjectPtr<AYagHUD>(this));

		// add the mother widget
		Viewport->AddViewportWidgetContent(SNew(SWeakWidget).PossiblyNullContent(YagHUDWidget.ToSharedRef()));
		YagHUDWidget->SetVisibility(EVisibility::Visible);


		// set up widgets
		SetupYagJournalWidget();
		YagJournalWidget->HideYagWindow();
		SetupYagMainMenuWidget();
		YagMainMenuWidget->HideYagWindow();
		[..............................................................................]    
	}

}

The setup function are filling the container (YagWindowContainer) with slots containing other widgets, like this:

	YagMainMenuWidget->YagWindowContainer->AddSlot()
	.FillHeight(1.f)
		[
			SNew(SOverlay)
			+ SOverlay::Slot()
			.HAlign(HAlign_Fill)
			.VAlign(VAlign_Fill)
				[
					SNew(SVerticalBox)
					+ SVerticalBox::Slot()
						[
							SNew(SButton)
							.ButtonStyle(&YagMainMenuWidget->YagGlobalStyle->YagButtonStyle)
							.TextStyle(&YagMainMenuWidget->YagGlobalStyle->YagButtonTextStyle)
							.Text(FText::FromString(Display(TextEnum::ACTION)))
							.OnClicked(YagActionWidget.ToSharedRef(), &SYagWindow::ToggleYagActionWindow)
						]
			 [.....................................................................]
				]
		];

Beside the complex nesting of elements, one thing i hate in my code is that all widget belong to the same class SYagWindow.

So i have to define them in the hud.cpp, then call delegates in the SYagWindow, which calls back functions in the hud.cpp.

That’s really ugly.

The way to get rid of that mess would be to have every widget be a daughter class of SYagWindow, but i couldn’t find a way to make inheritance work with widgets.

I enclose a new screenshot with most of the widgets made visible, so maybe it will make more sense.

Again, sorry for this very long post, hope you can understand something in this jungle :slight_smile:

Cheers

Cedric

My answer was too long for a comment (way above the allowed number of characters), so i posted it as an answer to the question, here below :slight_smile:

So if you disable your style everything works fine right?

Only thing I noticed is that you store reference to your button/text styles in a weird way.

&YagMainMenuWidget->YagGlobalStyle->YagButtonStyle)

Dont you have singleton instance of your “MainStyle” so you can access it anywhere in the same way without any other widgets references?

Take a look at shooter game Styles setup and try to reproduce it in your code (shouldnt be much work). Not sure if that will help but it’s the only thing I can think of.

I think you did put your finger on something important, as my problems started when i started using styles.

I will definitely try what you suggest and will update when done.

Again, thank you very much for your time and suggestions, very helpful, very appreciated :slight_smile:

I started to migrate my widgets toward a more orthodox architecture and it’s a success.

The first heavy widget i migrated displays itself immediately instead of the usual 1-2s.

I think the problem was in my super smart organization which finally reveals itself completely stupid :smiley:

Not sure but i think my setup functions inside the hud postinit function were being called every frame, so i was basically recomputing the entire architecture/content of the UI each frame. Not a good idea.

Moral of the story: stick to the standards :slight_smile:

I also have greatly symplified my calls to the styles. All in all some great improvements.

Thanks again Szyszek for taking the time to investigate, forcing me to rethink my code and pointing me to the right direction.

Cheers

Cedric

The final answer in case anyone reads this.

After rewriting and cleaning my code, the UI was more responsive but i still got a huge fps drop behind.

After a lot of tests, i found that the fps drop was only occuring when using text style, and had something to do with the font size.

When you define a text slate widget style in the editor, there is no default font, you have “none”, “none”, and no number for the font size.

I was only modifying the font size but let the font to the default “none”. This was what was causing the huge drop in performances.

When i selected a font (roboto, as it was the only one available), everything went 60+ fps, even with full UI deployed.

Moral of the story: don’t let everything at their default values :slight_smile:

Here, the absence of a default font was the troublemaker.

Man, so much time lost on that one !!!

Trying to figure out how to constrain scrollboxes in slate to a certain size, every time I attempt to constrain them to any height or width they DPI scale down instead of scrolling off the page, any advice?

Also sorry for resurrecting old thread

I think I used wrappers for each row for this problem. I can go into more details but your comment is 6 years old so probably won’t help you too much.