In this post, we will cover performance improvements and new tools available to advanced users for analyzing CPU and memory usage.
Reduction in GC Allocs for Computed Styles
During the internal update of UI Toolkit for resolving styles, Computed Style instances are created and shared amongst elements that match the same USS classes. Previously, Computed Style and related data were represented using objects which leads to a potentially large amount of GC allocations.
As of 6.5, this is no longer the case. Computed Style and related data are allocated using unmanaged memory which lowers GC pressure but also reduces overhead when passing this data to native code. For example, the layout related style properties are now directly accessed by the native layout library, without additional data copies.
In real world UIs, we have observed large reductions of GC allocations from the UI Toolkit styles. For example, UI Builder went from 3531 to 929 allocations(-73%), Shader Graph went from 1681 to 837 (-50%) and App UI (using the UI Kit sample) went from 8938 to 5102 (-42%).
For the next versions of Unity, we will continue to look for performance improvements in this area.
USS Stats Profiler
Unity has a new experimental tool called the USS Stats profiler. Once enabled in the Project Settings (UI Toolkit section), you can select any UI panel (similar to other debugging tools) and collect statistics about USS selectors.
This runs a full pass against all elements currently in the panel and will output some useful information for each stylesheet and each selector within it.
The tool is currently experimental because we are still working on better Profiler integration for UI Toolkit in general and we hope to streamline everything in the future.
In the meantime, while the UX of this window is still rough around the edges, we hope it can be useful to investigate performance issues regarding selectors.
New VisualElement.Clear() Options
When constructed, a new VisualElement instance is able to reuse resources previously used by other instances. However, there weren’t any real ways for some of these resources to be explicitly returned, except for native resources which are returned by the VisualElement finalizer, which does not happen deterministically.
For those reasons, we have introduced a new overload of the VisualElement.Clear() method which allows those resources to be made reusable immediately for an entire hierarchy. [Please note the API doc link is for 6.6 due to a mistake in the 6.5 version, which is being fixed. However functionality is identical between versions].
In UI intensive projects, using VisualElementClearOptions.RecursiveReleaseResources may help reduce peaks in memory usage (for example when transitioning between two very busy screens).
The good news is also that the new PanelRenderer component uses this overload when it is destroyed, aiming to have a memory friendly behaviour by default.
Additional Memory Profiler Visibility
As mentioned previously, UI Toolkit holds onto unmanaged memory which previously didn’t have any real visibility in Unity’s memory profiling tools.
Under a Unity-wide push to surface all allocations made by the engine inside the Memory Profiler, UI Toolkit now correctly tags this kind of memory for fine grained analysis. Obviously it is also very useful for our own team to analyze memory usage and help troubleshoot customer problems.
In order to support this, we added the MemoryLabel struct to the Unity public API to make those allocations visible to the Memory Profiler.
Improved Mesh Update Performance
On WebGL, Unity prevents stalls on WebGL by preventing writes to a buffer that was read by a recent draw call, and copying the data to a new buffer instead. This previously forced any change in a UI mesh (vertex+index buffers) to reupload the entire buffer. By using a staging buffer and GPU copies, UI Toolkit will now have much better mesh update performance on WebGL. Some performance tests were improved by a factor of 20x with this new approach. As you can imagine, it can be very expensive to upload 64k vertices when changing a quad of 4 vertices, so it was a much required improvement.
Our WebGPU implementation already used a form of staging but by improving our implementation, we were able to measure improvements of up to 4x.
Also, by tweaking how our system registers and handles partial mesh updates, we measured performance gains of up to 3x on some platforms.
Improved GPU Performance
UI Toolkit uses edge antialiasing that allows to display smooth edges, even in overlay where no MSAA is available. This antialiasing increases the shading cost, compared to that of regular geometry. We modified our tessellation so that, for some large geometries, only the parts that are close to the edge will compute the antialiasing. Extra triangles are required to achieve this, but much of the GPU cost comes from fragment shading on large shapes, so the benefits should outweigh the extra cost. On some lower-end platforms, the fragment shading cost of such cases was cut by up to 40% by using this strategy. This improvement will also be backported to previous versions of Unity.
Conclusion
As UI Toolkit matures into a production-ready solution, performance is treated as a core pillar of the roadmap rather than a constraint.
Recent work focuses on removing structural bottlenecks and improving efficiency across CPU and GPU. This includes foundational changes, such as moving computed styles to unmanaged memory to reduce GC pressure, as well as rendering optimizations that unlock significant gains on platforms such as WebGL.
At the same time, we are investing in profiling and diagnostics to give developers better visibility and control. Tools like the USS Stats profiler and improved Memory Profiler integration help make performance issues more transparent and actionable.
Looking ahead, our goal is twofold: make UI Toolkit fast by default, and equip teams with the tools to confidently scale, measure, and optimize their UI.


