最近做了福星转盘的功能,做完后发现当记录次数很多了以后会有性能问题,历史记录很多的时候,打开会卡。
第一反应
现象:当我看到优化需求的时候,“对历史记录做限制”,我第一反应,看下Profiler是什么,造成性能问题。看到是协程的调用。有出现高峰值,有高达200多M。在多次UI操作中,内存还是稳定增长。
处理:我估计是协程调用产生的,就在每个协程调用前加了StopCoroutine()方法。
问题:高峰值虽然降下来了,但是每次执行高峰值稳定增加20多M。而且最奇怪的是在于每次重启Unity后,还是会稳定出现这样的情况。
寻求主程指导(1)
现象:主程同样在看了Profiler后,给出建议是,用协程播放动画的效果改成用update执行。在处理以后,任然有内存高峰值出现。而且还是大于允许值6M。高峰值会有60多M,而且还会稳定增加。在关闭界面重新打开页面的时候,还是会特别卡。会有高达3.5G的GC。
指导建议:用协程播放动画的效果改成用update执行
处理:两次动画播放使用Update()处理。
问题:内存高峰值还存在,打开界面还是卡。这个阶段最大的问题在于认为是Unity有内存泄漏的bug。并没有想到是很多历史记录文字拼接带来的效率问题。
寻求主程指导(2)
现象:主程在看Profiler后,GameObject.Awake()有高达3.5G的GC。在看了UI界面制作的方式和对应功能配表上给出了优化意见,同时指出我对业务抽象处理不够。功能灵活性太差了。UI循序是UI策划那边排好的,我做的是获取组件有对应数据做出道具展示。有32个格子需要处理。完全可以抽象到给每一个格子处理。使用一个格子动态创建。还有所谓内外圈的效果,再抽象一层,业务逻辑就服务器根本不用管什么内外圈,根据权重比得到结果,再去看停留在内外圈的标志位值,扣除次数。
指导建议:对业务内容可以更抽象一层,UI界面创建,改用动态创建。实例化的格子太多造成卡顿。
处理:根据格子的属性不同,做不同的显示控制。动态创建。
问题:即使动态创建,还是有卡顿。关于动画的播放循序,不得不重新构思,主程给出建议是,完全可以有策划的配表实现,只要在表格设置Id循序就行。意识到是真正的问题是历史太长造成的卡顿。
历史记录的代码优化
代码如下
首先字符拼接会带来很多GC,在for循环中给UILabel赋值是反复赋值。特别是records很多的时候,会带来卡顿。代码优化如下
决解历史记录太长
现象: 在7次100连抽的后,会有UILabel的显示问题,“too Many Version on Panel”。UILabel展示范围超出去了。同时历史记录的,协议返回值的长度有8096字节。也就是需要找到合理的值。设计上是500条后,就把之前的全部删除,问题是每次抽取的长度并不固定。100次的长度肯能是18~26条之间。10次是5~
8之间。在系统策划商量后,决定为100条的长度,展示长度值小于100条。
处理:在Service给历史记录的List加值,然后再去判断长度,删除RemoveAt(0)。反复操作直到长度小于100.
问题:服务器返回协议最大值超出,服务器调整为90条。到这里性能的问题解了。
小结
这个优化的,最初觉得问题出现在动画上。结果方向还没有对。在尝试优化的基础上,反推发现,性能的问题并没有解决。从新思考造成问题的方向,确认问题所在,并给出了优化的方案。最终决解问题。
这个功能在开始做的时候,整个构思上,被策划需求所指引。并没有做到足够的抽象处理。造成面对策划需求变革的时候,不得不重新去更抽象理解整个业务内容。同时因为前期抽象不够,造成改动大架构的成本很高。服务器和客户端都要去改大量的代码。