常见原因
卡顿原因 | 解决方案 |
---|---|
多次遍历整个配置表找数据 | 加入缓存,因为代码一般局部性很大,而且缓存占用内存很小,因为保存的是config类的引用,不会有任何副作用 |
active/deactive | 参考这里优化显隐 |
同帧多次分发事件 | 收到一次事件界面就刷新一次,任务成就等模块就全局遍历一次,这都没有必要,做懒分发或者懒刷新,一帧只刷一次 |
解析文本开销大 | 参考这里,外部导入的动画模型等数据,能二进制就二进制 |
具体问题
1 | |
---|---|
卡顿表现 | 打开武将图鉴界面空白卡顿很久 |
卡顿原因 | 完全读取并反射解析了60列300行的配置表,18000次FieldInfo.SetValue和更多次的Dictionary查找,且Dictionary以System.Type做Key,Hash和Equals都很耗时 |
解决方案 | 武将属性60列只用到4列,专门新建一张图鉴配置表 |
2 | |
---|---|
卡顿表现 | 武将界面武将和碎片分页切换有卡顿 |
卡顿原因 | 使用了两个ScrollRect,每次切换一个Active另一个Deactive, ScrollRect自身加上武将Item的Enable/Disable耗时非常高 |
解决方案 | 参考这里使用移出屏幕方案代替Deactive |
3 | |
---|---|
卡顿表现 | 打开聊天界面空白卡顿很久 |
卡顿原因 | 聊天信息的加载未分帧,1帧实例化最多40条信息,且信息节点内部结构复杂,初始化时内部组件分条件显隐的Active/Deactive耗时高 |
解决方案 | 分帧实例化信息,从最新消息开始,不影响体验;内部组件消耗可通过拆分成不同类型预制体减少 |
4 | |
---|---|
卡顿表现 | 建筑升级界面点击升级后卡顿 |
卡顿原因 | 升级建筑会消耗资源,会奖励资源,获得经验,每条资源变化会触发一次事件分发,任务模块收到事件后遍历任务检查状态,升级界面收到事件后刷新界面;界面内升级条件、奖励预制体未使用对象池,不断销毁创建 |
解决方案 | 做懒分发,触发事件后只做脏标识,每帧只分发一次;界面用到的预制体使用缓存池 |
5 | |
---|---|
卡顿表现 | 副本战斗loading耗时长帧数多但每帧耗时不高 |
卡顿原因 | 100个AssetBundle.LoadFromFileAsync并发执行,yield return request 每帧只有1、2个返回 |
解决方案 | 使用while(!request.isDone){yield return null}代替yield return request |
6(存疑) | |
---|---|
卡顿表现 | 低端机特效出现方块 |
卡顿原因 | shader中使用了时间_Time,低端GPU的浮点数精度低,中间逻辑还是没理清楚 |
解决方案 | 不使用_Time,用脚本设置全局时间变量,shader读取 |
7 | |
---|---|
卡顿表现 | 关闭全屏界面,返回主界面卡顿 |
卡顿原因 | ScrollRect.Enable会触发Rebuild,耗时很高,偶尔触发Font.CacheFontForText,耗时恐怖 |
解决方案 | 同 2, 使用移出屏幕替代Active/Deactive |
8 | |
---|---|
卡顿表现 | 武将图鉴界面点开武将模型卡顿 |
卡顿原因 | 武将展示模型使用的spine动画,json文件解析的GC和耗时都很高 |
解决方案 | 在由于武将很多,不确定玩家会点哪一个,没法预加载;新版spine支持导出二进制配置取代json,耗时减少80%以上,GC也小 |