惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
GbyAI
GbyAI
Google DeepMind News
Google DeepMind News
Jina AI
Jina AI
B
Blog
aimingoo的专栏
aimingoo的专栏
酷 壳 – CoolShell
酷 壳 – CoolShell
T
The Blog of Author Tim Ferriss
Last Week in AI
Last Week in AI
月光博客
月光博客
H
Help Net Security
V
Visual Studio Blog
量子位
A
About on SuperTechFans
博客园 - Franky
人人都是产品经理
人人都是产品经理
N
Netflix TechBlog - Medium
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
Martin Fowler
Martin Fowler
Microsoft Security Blog
Microsoft Security Blog
博客园 - 叶小钗
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Unity UGUI Optimization: Why Rendering.UpdateBatches Can ...
GameOptim · 2026-06-15 · via DEV Community

Intro

A high Rendering.UpdateBatches cost in Unity’s UGUI often signals excessive SyncTransform activity. This article breaks down how TransformDirty propagation happens, why frequent SetActive is a common trigger, and how separating dynamic and static Canvas structures can significantly reduce UI overhead in production projects.


Q:

In the main scene report from GameOptim GOT Online, we noticed that UGUI consistently takes around 7ms, which is even higher than in the combat scene.

From the call stack, a large portion of the cost appears to come from Rendering.UpdateBatches itself.

Could this be caused by calling SetActive too frequently in the project?

A:

Your direction is correct.

There is a high probability that frequent SetActive calls are triggering SyncTransform, which is a very typical optimization pitfall in UGUI.

However, while SetActive is one of the most common causes, it is not the only one. Operations such as RectTransform size changes, LayoutGroup rebuilds, ContentSizeFitter updates, and SetParent can also continuously trigger SyncTransform. Further confirmation still requires checking the call stack.

The profiling path here is relatively clear:

The main performance entry point of UGUI is Rendering.UpdateBatches, but the internal breakdown of this stage determines where the actual problem lies.

Under normal circumstances, most of the cost is concentrated in the SendWillRenderCanvases node.

But in this project report, the unusual part is that the self-time of UpdateBatches itself accounts for an abnormally large portion, which points to a specific internal function:

SyncTransform

Within a sampling window of 4000 frames, the number of SyncTransform calls remains around 300.

This call count is highly correlated with the self-time percentage of UpdateBatches:

the higher the call count, the higher the self-time, and the overall UGUI cost increases accordingly.

It is important to note that a high SyncTransform call count is not the root cause by itself.

It is the result of continuous TransformDirty generation.

When a UI node’s active state, hierarchy, position, or size changes frequently, Unity continuously synchronizes Transform data.

These changes are then propagated to the Canvas system, triggering batch rebuilds and Canvas updates.

Therefore, when investigating SyncTransform, the focus should not only be on the cost itself, but on identifying what is continuously generating TransformDirty.

Why does SetActive trigger SyncTransform?

When GameObject.SetActive(true) is called, the UI hierarchy containing that node triggers Transform synchronization and Canvas dirty flag updates.

In complex Canvas hierarchies, this impact can spread to a large number of related UI elements.

If certain UI elements are shown and hidden at high frequency—such as combat HUD floating damage text, status icons, or timers—every visibility change can cause the entire Canvas to resynchronize its Transforms.

This causes the number of SyncTransform calls to continuously increase.

A more subtle case occurs when frequently toggled UI elements share the same Canvas as static UI.

In this case, every SetActive operation can force the static portion of the Canvas to be recalculated as well, creating a large amount of unnecessary rebuild overhead.


Optimization Suggestions

Use localScale 0/1 instead of SetActive for high-frequency visibility toggles

For UI elements with high toggle frequency and short lifecycles (such as floating damage text, status icons, and timers), switching between localScale = 0 and localScale = 1 can avoid continuous SyncTransform triggering.

For medium-to-long lifecycle elements with high reuse frequency, object pooling should be prioritized.

For cases where position and state need to be preserved and only temporary hiding is required, using an Alpha fade approach may be more appropriate.


Separate dynamic and static UI

Move frequently toggled UI nodes out of the main Canvas and place them under a dedicated Canvas.

This ensures each visibility change only affects the smaller dynamic Canvas, while the static UI under the main Canvas remains untouched.


Inspect nested Canvas coverage

If a parent Canvas contains a large number of child elements, frequent updates in child nodes can still affect the parent.

By combining the SyncTransform call count curve with scene-level performance peaks, it is possible to trace back which Canvas is being repeatedly invalidated.