5.3 编辑器性能:大数据与卡顿
编辑器卡顿有几个专属来源:资产加载、UI 重绘、编辑器 Tick、以及内容浏览器的索引。这一节给出每个来源的诊断方法和优化手段。
症状 → 来源速查
| 症状 | 大概率来源 | 第一步 |
|---|---|---|
| 工具面板卡/掉帧 | Slate UI | Slate Insights(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/slate-insights-in-unreal-engin-e81c) |
| 打开工具后整体编辑器慢 | Tick 后台循环/绑定重函数 | 注释掉怀疑段二分 |
| 批量操作卡 30 秒+ | 同步资产加载 | 分批 + 异步 + 进度条 |
| 编辑器启动慢 | 自动运行的工具/启动脚本 | 先排除 |
| 内容浏览器搜索慢 | 资产数量 | 减少项目视图过滤 |
| 保存慢 | 大关卡/引用链 | 拆关卡、卸载未引用 |
资产操作性能的分级
| 操作 | 1 个资产 | 1000 个资产 |
|---|---|---|
| AssetRegistry 元数据查询 | ~0ms | ~100ms(可接受) |
| 同步加载 | ~50ms | 10s+(必须优化) |
| 异步加载 + 分帧 | 不适用 | 流畅(每帧 10~20 个) |
| 保存 | ~100ms | 分钟级(分批+进度) |
批处理工具的标配:异步加载 + 每帧处理固定数量 + FScopedSlowTask 进度条。用户能接受「跑 2 分钟但有进度」,不能接受「卡死 30 秒假死」。
// 分帧批处理骨架
void FBatchProcessor::Tick()
{
const int32 BatchSize = 16;
for (int32 i = 0; i < BatchSize && CurrentIndex < Assets.Num(); i++, CurrentIndex++)
{
ProcessAsset(Assets[CurrentIndex]);
}
SlowTask.EnterProgressFrame(BatchSize);
if (CurrentIndex >= Assets.Num()) { Finish(); }
}
资产引用与「保存传染」
保存一个资产时,引用它的关卡/资产也可能被标记脏。工具批量保存后关编辑器,看到「是否保存 N 个其他资产」的弹窗——就是这个机制。控制:
- 工具只保存它真正改过的资产(MarkPackageDirty 只在改值后调)
- 需要时提供选项「连同关卡一起保存」
内容浏览器是性能黑洞
内容浏览器的资产列表、缩略图渲染、筛选都在主线程。项目资产特别多时,编辑器任何操作都会被拖。缓解:
- 分目录组织(单目录 < 1000 资产)
- 关闭不用的筛选器/集合
- 工具做批量操作时避免触发内容浏览器刷新(每改一个资产同步一次浏览器,1000 次刷新 = 卡死)
工具自身卡顿的三个典型病根
① 绑定函数重(见 2.5):每个列表行的文本/图标绑了重函数。
② 每帧 RequestListRefresh:ListView 重建所有行。改为数据变化时才 Refresh。
③ 委托泄漏:工具窗口关了,但注册的编辑器全局委托没解绑,Tick 一直在后台跑。这类 bug 的特征是「用过一次工具后编辑器就一直慢」。解决:窗口的 OnClosed / 模块 Shutdown 里解绑所有委托。
一个测量模型
编辑器性能问题的惯用法:开/关对比。症状发生时,关掉所有自研工具窗口,看是否恢复——定位到「是哪个工具」后再深入 Slate Insights / profiler。盲进分析器面对全编辑器的开销容易迷失。
团队侧的规范
- 发布工具前做一次「大项目压测」:在包含大量资产的工程里跑一遍主流程
- 监控编辑器 FPS:组内约定开发机的「编辑器空载 FPS」,异常时优先怀疑工具
心得:编辑器性能问题有个特别恶心点——「用户自己的项目资产量」决定要不要暴露。开发期小 demo 里一切正常的工具,上线到几十 GB 资产的项目就卡死。压测做在前面是唯一解。
