UI 性能

自动关联目录:UI 性能

1. 定位

UI 的成本主要在游戏线程:布局计算(Slate 的 Layout/Paint)与每帧重建。它不像渲染那样能在 GPU 上并行,所以 UI 卡会直接吃掉 Game 线程预算。

一句话定位:UI 优化的第一原则是"别每帧重做"——缓存、失效驱动、减少 Widget 数量。

2. 三个核心手段

手段机制适用
Invalidation Box缓存子树的绘制结果,只有失效时才重画内容不常变的 UI
Is Volatile反过来——标记这个 Widget 每帧都要重画确实每帧变的(如倒计时)
ListView 复用条目控件复用,长列表必备背包、排行榜

Invalidation Box + 非 Volatile 是默认应该做的:把不变的 UI 包起来,让它不再每帧重画。

注意:Invalidation Box 内的 Widget 如果标了 Is Volatile,缓存就失效了——两者是矛盾的,只对真正每帧变的东西开 Volatile。

3. 常见成本来源

来源说明
属性绑定每帧求值(见 UMG 深入)
Tick 里刷新每帧重建布局
Widget 数量每个 Widget 都有布局与绘制成本
长列表不用复用ScrollBox + 大量 Widget
合批失败不同材质/图集打断合批
3D UI(WidgetComponent)每个都是一次渲染(见 3D UI)
富文本解析与布局成本

4. 合批

要点说明
同材质同图集更易合批把 UI 图片打成图集
减少材质切换尽量共用材质
注意渲染顺序层级穿插会打断合批

5. 参数与调试

命令 / 设置作用
Invalidation Box缓存绘制
Is Volatile强制每帧重画
Widget.Refresh / 相关统计Slate 耗时
Unreal Insights看 Slate 的 Layout/Paint 耗时
stat slate / Slate 统计UI 耗时
Show > Widget 相关调试绘制

6. 代价与权衡

设计收益代价什么时候不该用
Invalidation Box大幅省缓存内存;内容变化时失效成本每帧变的 UI 不该包
Is Volatile保证及时更新每帧重画一般不标
ListView 复用长列表必备实现稍复杂条目少时 ScrollBox 更简单
图集合批资产管理成本简单 UI 不必
减少 Widget 数直接省UI 表达受限平衡

7. 踩坑与排查

坑现象怎么验证
大量属性绑定UI 卡改委托驱动
Tick 刷新文本每帧重建改事件驱动
长列表用 ScrollBox卡改 ListView
Invalidation Box 内标 Volatile缓存失效检查 Volatile 标记
Widget 数量爆炸布局慢合并与复用
3D UI 太多渲染成本高见 3D UI 篇
UI 打开时一次性构建太多打开瞬间卡顿分帧构建或预创建

8. 排查顺序

1. stat unit → Game 高才可能是 UI
2. 查属性绑定与 Tick 刷新 → 改委托/事件驱动
3. 加 Invalidation Box,检查 Volatile
4. 长列表 → ListView
5. Widget 数量与合批
6. Insights 看 Slate 的 Layout/Paint 明细

参考