1.关于Cpu耗时
Cpu主要分Layout(布局)和Render(渲染)两部分
需要关注的函数:
1.Canvas.SendWillRenderCanvases
这个函数的消耗包括:UI元素更新,比如图片替换、文本的内容/颜色变化等。
优化方式:降低更新UI的频率,如果存在一些高顶点消耗的元素,比如使用了Rich Text(会生成多个字号)、Outline、Shadow的Text,使用了Tiled的Image等,考虑用艺术字代替。
2.BuildBatch & EmitWorldScreenspaceCameraGeometry
Canvas.BuildBatch,合批消耗,为UI元素合并的Mesh需要改变时所产生的调用,也包括UI元素位移,任一元素发生位移都会引起Redraw,BuildBatch由主线程发起,由子线程处理合批,当子线程压力过大,使主线程等待引起卡顿,等待的耗时为EmitWorldScreenspaceCameraGeometry。
优化方式:动静分离,降低网格更新的复杂度。
3.SyncTransform
避免频繁SetActive,造成Canvas下其他元素触发SyncTransform,可以用SetScale代替,Image用enable代替等,或者讲Canvas拆分。
4.EventSystem.Update
该函数为触摸释放时触发,该函数本身有较高的CPU开销时,通常都是因为调用了其他的较为耗时的函数引起。
优化方式:默认关闭Raycast Target,减少组件参与轮询。
5.UI DrawCall
关于合批,在Cpu阶段,剔除遮挡后,先进行深度排序(遮挡关系),根据图集,材质id分成不同的depth,再进行合批,在深度排序时,覆盖关系是有效的,在确定深度之后,合批时候已经不再考虑覆盖关系了。(重要)
rectMask2D比Mask更节省性能,原因是Mask的机制是用不同材质对显示区域进行控制,会至少产生2个额外的drawcall,而rectMask2D依赖于RectTransform,被遮挡的区域不进行渲染。
对于Alpha为0的Image,需要勾选其CanvasRender组件上的Cull Transparent Mesh选项。
2.关于内存
内存上主要是图集的使用,最多不要超过2个Atlas。
关于GC之后再做总结,不限于UI方面,主要是细节和代码质量。
3.关于GPU
主要优化的内容有复杂的vertext或pixel shader计算以及overdrow造成过多的像素填充。
比如shadow、outline带来字体的顶点数问题,Tiled格式的Image带来的顶点数问题等。