Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Testing performance between UI Toolkit and UGUI

Discussion in 'UI Toolkit' started by RichardJanssen, Feb 19, 2021.

  1. RichardJanssen

    RichardJanssen

    Joined:
    Apr 21, 2017
    Posts:
    14
    Hello,

    I've been trying to test the performance changes between UI Toolkit and UGUI. I'm loving the workflow of UI Toolkit. So far I've heard that the UI Toolkit is better performance wise and I wanted to test that. After testing two identical (as far as possible) UIs the profiler showed that UI Toolkit took way longer than UGUI to do the same thing.

    I made two UIs that "spawn" in 100 buttons in. For UGUI with Instantiate. For UI Toolkit with CloneTree. When turning these UIs off and on in code, UI Toolkit takes 2 times as long as UGUI currently. The UGUI UI I turn the parent Panel off with gameObject.SetActive() and the UI Toolkit UI I turn the parent VisualElement off with panel.style.display = DisplayStyle.None.

    For both tests I tested in Editor and in a Build, it's relatively the same. The screenshots are from the Editor tests.

    What could be the reason that UI Toolkit is slower?

    UGUI_UI.png
    The UGUI UI.
    UGUIPerformance.png
    The UGUI Profiler.
    UGUI_UI.png
    The UI Toolkit UI.
    UIToolkitPerformance.png
    The UI Toolkit Profiler.

    The versions I'm using are the following:

    Unity 2021.1.0b6.1892
    UI Builder 1.0.0-preview.12
    UI Toolkit 1.0.0-preview.14
     

    Attached Files:

  2. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    We are currently looking into ways to improve the performance when going from display:none to display:flex, as this use-case currently regenerates the whole geometry from scratch.

    A simple workaround is to set the opacity of the parent element to 0 instead of setting display:none. This will keep the rendering hierarchy intact and will simply skip the rendering of that tree.

    EDIT: Note that "display:none" and "opacity=0" are not always equivalent, as setting the display:none value will impact the layout.
     
    Ali_V_Quest likes this.
  3. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    771
    Hello, thanks for sharing this with us.

    There also seems to be some unnecessary allocations or re-allocations of text data. We may consider this a bug, I'll post back here

    Thanks
     
    Last edited: Feb 19, 2021
  4. HugoBD-Unity

    HugoBD-Unity

    Unity Technologies

    Joined:
    May 14, 2018
    Posts:
    492
    Really interesting, thank you for bringing it up!

    One reason why the text allocation is so big is that the TextInfo struct was duplicated in Preview-14 because we couldn’t have a direct dependency on TextCore. This is now fixed in our development branch and will be available to users in Preview-15.

    However, there seems to be a deeper issue here. We shouldn't be regenerating the TextInfos after a change in display. We'll investigate and keep you updated.
     
    Ali_V_Quest and RichardJanssen like this.
  5. RichardJanssen

    RichardJanssen

    Joined:
    Apr 21, 2017
    Posts:
    14
    Thanks, I will try the workaround and see how that changes things! As a clarification, my use-case is that I want to turn panels on and off similar to how you do it in UGUI with gameObjects or the equivalent of that in UI Toolkit. What would be the best approach to turn parts of the UI off and on in UI Toolkit, I've noticed there are a couple of options:

    1. DisplayStyle
    2. Opacity
    3. Visible
    4. SetEnabled()

    Thanks for the quick replies!
     
  6. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    Changing the opacity is the fastest option at this time in most situations. Followed by changing the visibility. I think changing the display value is similar to enable/disable (both are slow right now).
     
    nancycdm2021 likes this.
  7. RichardJanssen

    RichardJanssen

    Joined:
    Apr 21, 2017
    Posts:
    14
    Good to know, thanks for the quick reply!
     
  8. RichardJanssen

    RichardJanssen

    Joined:
    Apr 21, 2017
    Posts:
    14
    I tried using "panel.style.opacity = 0" for making it invisible and used "panel.style.opacity = 1" to make it visible again. UI Toolkit still seems to be slower than UGUI. To be a bit more specific how I implemented the buttons in UI Toolkit: I have a VisualTreeAsset in code that is a SerializeField which I set through the editor. Then to spawn in each button I call "visualElementParent.Add(buttonReference.CloneTree());"

    Could this be related to UI Toolkit or to how I initially "spawned" in the buttons in UI Toolkit?

    UIToolkitPerformanceOpacity.png
    Below is a screenshot of the profiler when using opacity.
     
  9. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    How you create the element should not matter in this case.

    What's odd is that we can see a lot of time is spent regenerating the geometry (TessellateRect/Border). This shouldn't happen when only changing the opacity.

    I'll make a few tests and come back to you.
     
    Ali_V_Quest likes this.
  10. uMathieu

    uMathieu

    Unity Technologies

    Joined:
    Jun 6, 2017
    Posts:
    396
    SetEnabled() on VisualElement doesn't have the same effect than on GameObjects. SetEnabled will toggle the enable pseudo state and will prevent some events to be dispatched to the elements. They'll still be visible (think of a disabled text field)
    Changing the enabled flag on the UIDocument component is the same as doing Add(x)/x.RemoveFromHierarchy() which will be the slowest of all options.
    To your list, I would add another one, event if it might not be the cleanest one:
    5. setting usageHint.DynamicTransform and setting ve.transform.position = new Vector3(-10000,-10000, -10000)

    To be honest, showing/hiding large parts of the ui tree is problematic performance-wise at the moment and it clearly should not. We'll improve this.
     
    Ali_V_Quest, Kirsche and TimHeijden2 like this.
  11. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    What happens with tied to the element events? Just because `window` isnt visible does not means cripts arent active, right? It still will receive event, and process coroutines if any?
     
  12. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    I had a look. It turns out that we consider opacity transitions from zero to non-zero in a similar manner as style.visible = true. So the performance isn't great. Going almost transparent (instead of fully transparent) doesn't show the same performance issues.

    Thanks for reporting, we'll provide more efficient visibility changes in the future.
     
    Last edited: Feb 23, 2021
  13. PaoloAm

    PaoloAm

    Joined:
    Jul 15, 2019
    Posts:
    28
    Sorry for bringing this topic back up again, did you find what would be the most performant approach to hide elements visually and event wise (so clicking on it does not interact with them and neither bother anything below)?

    I am asking this because we use a lot the display flex none approach. Both to display and hide modals entirely and both to change dinamically the view in the open panels.

    Example:
    You have a modal open with on the left a list of toggles and on the right a container. When the user click on each toggle it will display none the open tab on the right and will display flex the tab requested.

    Thanks
     
  14. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    From a rendering perspective, setting the opacity to 0% is the most performant way to hide an element. Unfortunately, even at 0% opacity, the element will still respond to events. So, setting the opacity to 0% and moving the element out of the way (by changing its position) may be the most performant solution. When doing that, make sure the element has the DynamicTransform hint set, so that moving the element will be a cheap operation.

    We will provide performance improvements in the future to be able to change the visibility and display styles more efficiently.
     
    Ali_V_Quest likes this.
  15. PaoloAm

    PaoloAm

    Joined:
    Jul 15, 2019
    Posts:
    28
    Thanks for the explaination, I will work on that. Please keep us updated on the performances improvements, it was so easy to implement as a flow.
     
  16. PutridEx

    PutridEx

    Joined:
    Feb 3, 2021
    Posts:
    1,136
    How does UI toolkit performance compares to ugui at this point?
     
    Ali_V_Quest likes this.
  17. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    Did some reading of the reports and it seems like uGUI, followed best practiced in depth, beats it by a far.
    UI Tookit can still buy you with its extensibility and ease of use
     
    mandisaw and ArthurTheKing like this.
  18. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    397
    The problem with using "opacity" or "visibility" instead of "display" for hiding elements is that they still occupy their space in the layout.

    What I realized is that creating new UI elements during runtime is much slower and causes lag spikes in WebGL.
    So what I do when I have dynamic lists is that I spawn enough at startup and then reuse them as the list changes. Like a pool.
     
    mandisaw and AmazingRuss like this.
  19. jiraphatK

    jiraphatK

    Joined:
    Sep 29, 2018
    Posts:
    293
    That's unfortunate. I really have high hope that UITK would solve the performance problem of UGUI. I have seen old threads comparing UITK and UGUI and UITK always beat it. What happened? :(:(
    I have not use UITK personally since it lacks the critical features our company app need (Emoji support, variable height list view, custom shader & ui particle).
     
  20. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    397
    In my experience:
    During animations there are a lot of vertices generated and Events fired
    Creating UI elements creates a lot of garbage that cause lag spikes
     
    jiraphatK likes this.
  21. HTOE

    HTOE

    Joined:
    Nov 17, 2017
    Posts:
    1
    Have you improved this yet? Or what is the current best practice for solving this use case, as many others I'm experiencing some pretty serious lag spikes.

    Thanks in advance.
     
  22. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    Changing the opacity is still the fastest way to show/hide hierarchies. We tried to improve on the visibility value, but the styling system caused some performance issues, so these perf improvements will come later.
     
    restush96 and chriseborn like this.
  23. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    any updates on this ?
     
  24. paolo-rebelpug

    paolo-rebelpug

    Joined:
    Sep 27, 2021
    Posts:
    22
    Would love to know as well if there is any update. We can have a drop of 150fps when opening a modal full of content.

    Thanks!
     
  25. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    In 2023.1 there are some optimizations related to the display flex/none situation. The tessellated geometry is cached and saved for later when doing a display:none, in case the content is displayed later.

    If possible, you can take a profiler capture when opening the content, this will help understand where the time is spent.

    Note that when spawning a new VisualElement hierarchy full of content, the usual "first frame" cost apply, meaning that the full allocation and tessellation of the primitives will occur. Pre-loading would probably help in that situation.
     
  26. paolo-rebelpug

    paolo-rebelpug

    Joined:
    Sep 27, 2021
    Posts:
    22
    Good for the optimization, sadly we are already live with the game on version 2021, I would be really scared to do the jump.

    testing.jpg

    I am not really sure I understand the issue here, but it seems that loading all the elements in the scrollview is very costly.

    We preload and set everything when the game start, the only thing it does is that when it opens the panel it display everything.
     
  27. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    Unfortunately, it's quite difficult to understand these profiler stats without more context about how the elements are loaded into the scrollview, how they are displayed etc.

    If you have a small project you can share here, please do so. You can also report a new bug (Help > Report a Bug...) and paste the bug number here, we'll have a look.
     
  28. paolo-rebelpug

    paolo-rebelpug

    Joined:
    Sep 27, 2021
    Posts:
    22
    Thanks for the information, I'll try to figure out what is going on. Sadly it wouldn't be easy to reproduce in a small project quickly so I would need to wait on that.
     
    mcoted3d likes this.
  29. laszlmol

    laszlmol

    Joined:
    Mar 6, 2023
    Posts:
    1
    Hi, any update on performance? I would be really interested in performance measurements in the UGUI vs UIToolkit topic. We are planning to reimplement the UI of our application and it's a question if we should use UGUI or UIToolkit.
     
  30. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    This is difficult to answer. On the CPU side, some use-cases are faster in UI Toolkit, others are still more efficient in UGUI. Layout and styling can be expensive in UI Toolkit, but they provide much more flexibility than UGUI. UI Toolkit is able to render with fewer draw-calls, but the fragment shader is, at this time, much heavier.

    Every release we try to bridge the gap between UI Toolkit and UGUI, with the aim that UI Toolkit outperforms UGUI in virtually every use-case. We are not there yet, but we are working on it.

    For your particular situation, you will have to evaluate your use-cases with both, by doing simple prototypes and running them on the target devices. Even though the UI Toolkit shaders are more hungry, they perform quite well on most modern platforms.

    This thread started by discussing the showing/hiding of large amount of elements. We made some progress by improving the speed of the initial tessellation of the elements, but it's still an expensive operation. More optimizations are coming soon, but in the meantime, preloading, caching and showing/hiding the elements by playing with the opacity will help.
     
    mandisaw likes this.
  31. paolo-rebelpug

    paolo-rebelpug

    Joined:
    Sep 27, 2021
    Posts:
    22
    Thanks for the update and all the information.

    The opacity is still not a solution for us since in many cases it does still register events and the rest of elements still consider it when handling the responsiveness. We do the caching and everything but we still rely heavily on the display flex/none.

    Hopefully in the future it will be more performant :)
     
  32. huwp

    huwp

    Joined:
    May 22, 2013
    Posts:
    33
    I've found that the biggest cause of lag (2021LTS, android), is first load of textcore fonts, that causes a significant stutter. When that's done, UITK actually performs faster than ugui for my use case.
     
  33. garrett-at-bi

    garrett-at-bi

    Joined:
    Apr 4, 2023
    Posts:
    1
    Will this be backported to LTS?
     
  34. mcoted3d

    mcoted3d

    Unity Technologies

    Joined:
    Feb 3, 2016
    Posts:
    998
    I'm afraid this one is not backportable given the extent of the refactor that was required.