godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.8k stars 21.13k forks source link

Loading large RichtTextLabel takes a long time #96475

Open maran opened 2 months ago

maran commented 2 months ago

Tested versions

4.3.stable

System information

Pop!_OS 22.04

Issue description

My app starting more slowly with every version I released. I've been debugging it for most of the day only to find out that my change-log was the culprit. I've been using a RichtTextLabel and just added to this label with every release. Right now loading the scene which includes the release notes takes about 6 seconds on my 11th gen i7.

Steps to reproduce

  1. Add a RichtTextLabel to a scene.
  2. Create a nice Lorem Ipsum and copy it a few dozen times into this RichTextLabel.
  3. See your scene loading slower with every paragraph added.

Minimal reproduction project (MRP)

RichTextLabel.zip

RedMser commented 2 months ago

By turning on the Threaded checkbox in your MRP, the scene loads instantly

image

maran commented 2 months ago

Thanks for that, it also helps reduce load times a lot on my production app. Any downside to using threaded? If not should it perhaps be a default option? On mobile devices the increase in performance is sadly less visible.

RedMser commented 2 months ago

Any downside to using threaded?

None are documented, the PR only says that it is off by default but not why... I assume spawning a thread has enough overhead for small and simple RTL, that there is no point to have it on by default.

aXu-AP commented 2 months ago

Any downside to using threaded?

It's a little hidden in the docs under bbcode tutorial, but it says:

Enable the Threading > Threaded property in RichTextLabel. This won't speed up processing, but it will prevent the main thread from blocking, which avoids stuttering during gameplay. Only enable threading if it's actually needed in your project, as threading has some overhead.

So I guess if you have multiple smaller RichTextLabels, it can affect performance negatively. For long texts I think it's best to have them run on background.

Also the reason why it's disabled by default might be in that the behavior is easier to understand when it's blocking. Ie. you add the label, get its size, do something. When using threading, you need to wait for it to finish. Also often it's preferred that all elements will be rendered in the first frame when ui shows up, even if it means a small delay for this first frame.

Mickeon commented 2 months ago

Also the reason why it's disabled by default might be in that the behavior is easier to understand when it's blocking.

Correct. You'd expect the label to be changed relatively instantly. By enabling threaded you should expect at least one frame where the label appears invisible or only partially generated. The flickering is more noticeable if the text is very short, and is most definitely not desired unless you're generating a web page's worth of text. In OP's case, that's exactly what threaded is for.