Quick answer: A single changing element marks the whole Canvas dirty — the entire batch rebuilds. Put dynamic elements (timers, health bars) on their own Canvas, separate from static UI.

The Profiler shows a Canvas.SendWillRenderCanvases / rebuild spike every frame. A constantly-updating score text is dirtying the whole HUD canvas.

One Dirty Element = Whole Canvas Rebuild

UGUI batches a Canvas’s geometry. Change any element on it — text, position, color — and the whole Canvas regenerates its batches. A per-frame timer text rebuilds your entire HUD every frame.

Split by Update Frequency

A nested Canvas component creates a separate batch boundary — changes inside it don’t dirty the parent.

Other Wins

Verifying

Profiler: the rebuild spike now only covers the small dynamic canvas. The static HUD canvas shows zero rebuilds during gameplay. Frame time drops and steadies.

“Canvases rebuild as a unit. Separate ‘changes every frame’ from ‘never changes’.”

Rule of thumb: if it animates or counts, it gets its own Canvas. Everything else can share one static canvas.