Unity UI That Does Not Tank Your Frame Rate
A single animated counter can rebuild an entire screen sixty times a second. Here is why, and the handful of changes that remove most UI cost from a mobile game.

Unity rebuilds an entire canvas whenever anything on it changes. One animated score counter on a canvas holding fifty static elements rebuilds all fifty, every frame. Splitting canvases and turning off unnecessary raycast targets removes most UI cost in a mobile game.
Why this matters
UI is the least suspected cause of poor mobile performance and one of the most common.
The reason is that it looks static. A screen with a heads-up display and a few buttons appears cheap, and profiling frequently shows it costing more than the gameplay behind it.
The fixes are configuration rather than architecture, which makes this one of the highest-return afternoons available on a mobile build.
Why canvas rebuilds are expensive
A canvas gathers its child elements into geometry the GPU can draw. That process is the rebuild.
The rebuild is not incremental. Change one element and the whole canvas regenerates, then re-uploads. Cost scales with the number of elements on the canvas, not with the number that changed.
That is why a single frequently changing element is so damaging. It converts every other element on that canvas into per-frame work.
The expensive thing is not your animated counter. It is everything sharing a canvas with it.
Splitting canvases correctly
The fix follows directly from the cause: separate things that change from things that do not.
A structure that works for most mobile games:
- A static canvas for backgrounds, frames, and anything that never changes during play.
- A dynamic canvas for counters, timers, health bars, and anything animating.
- A separate canvas per screen or panel, so an inactive screen costs nothing.
- A canvas for world-space elements such as floating damage numbers, if you use them.
Two cautions. Each canvas is a separate draw call batch, so hundreds of canvases carry their own cost. Two to five per screen is a reasonable range.
Also avoid nesting a dynamic canvas inside a static one and expecting isolation. Nested canvases do isolate rebuilds, but layout changes can still propagate, so test rather than assume.
Raycast targets and the free win
Every UI element with Raycast Target enabled is tested on every touch, and it is on by default.
A screen with a hundred images and text elements performs a hundred tests per touch event, when perhaps five of them are actually interactive.
The fix takes minutes.
- Turn off Raycast Target on every non-interactive element. Text, decorative images, frames, icons inside buttons.
- Leave it on only for buttons, toggles, sliders, and scroll areas.
- Use a single transparent image as a blocker behind a modal, rather than relying on many elements.
This is the single cheapest UI optimisation in Unity and it is very commonly missed. It costs nothing visually.
Layout groups and their cost
Layout groups compute positions at runtime, and they recompute whenever their contents change.
They are convenient during development and expensive at scale, particularly when nested.
| Situation | Recommendation |
|---|---|
| Fixed layout that never changes | Remove the layout group once the design settles |
| List that changes rarely | Keep the group, but disable it after building the list |
| Long scrolling list | Do not use a layout group; reuse a screenful of rows |
| Nested groups | Avoid entirely, since cost compounds |
The scrolling list case is the important one. A list of two hundred rows built as two hundred objects inside a layout group is slow to build and slow to scroll. Reusing a fixed number of visible rows is the standard fix and it pairs with the pooling approach in Object Pooling in Unity.
Text rendering and TMP settings
Text is the most frequently updated UI element in most games, which makes its settings worth attention.
- Use TextMeshPro rather than legacy text. Better rendering, fewer draw calls, proper atlases.
- Do not update text when the value has not changed. Comparing before assigning removes a large amount of pointless rebuilding, particularly in per-frame score updates.
- Avoid string concatenation per frame, which allocates and eventually triggers collection.
- Keep font atlases tight. A dynamic atlas containing a full character set for a game using thirty characters wastes memory.
- Watch rich text and auto-sizing. Auto-sizing recalculates on change and is worth disabling once layouts are fixed.
The allocation point connects to the stutter causes in Unity Mobile Performance.
Profiling UI specifically
General profiling hides UI cost inside rendering. Look for it directly.
- Open the profiler on a device and find the canvas rebuild entries in the CPU timeline.
- Watch the rebuild count, not just the time. A high count means the split is wrong.
- Toggle canvases off one at a time to attribute cost. Crude and effective.
- Check batching in the Frame Debugger, since overlapping elements can break UI batching and multiply draw calls.
- Test with the UI visible and hidden to get a clean measurement of its total cost.
If disabling the interface materially improves frame rate, the problem is here rather than in gameplay.
What we would do
Set the canvas split at the start of the project as a convention: static, dynamic, and one per screen. Retrofitting it later means moving elements around and re-testing every layout.
Make Raycast Target off the default in your team's UI prefabs, and turn it on deliberately for interactive elements. Defaults are more reliable than remembering.
Then check the value before writing to any text field. It is a one-line habit that removes a surprising share of per-frame UI work, especially in games with visible counters.
The short version
- A canvas rebuild regenerates everything on that canvas, not just what changed.
- Split into static, dynamic, and per-screen canvases, keeping the total modest.
- Turn off Raycast Target on every non-interactive element.
- Remove layout groups once layouts settle, and never nest them.
- Use TextMeshPro and skip updates when the value has not changed.
- Profile canvas rebuild counts on a device, not just total render time.
Turn off Raycast Target across your interface and split one busy canvas this week. If your frame rate improves noticeably when the UI is hidden, send us the build.
Related reading: Unity Mobile Performance, Object Pooling in Unity, and Cut Your Unity Build Size in Half.
Got a game idea? We build it.
You bring the concept. We design, build, test and launch it, and you own 100% of the finished game.
Share Your Game Idea →