自从到现在的公司半年一来,业务上一直在不停的迭代。为了维持版本的迭代速度,代码review变得不再像之前那么严苛。导致近期出现了几个比较严重的问题,趁着周末的时间,使用Time Profiler好好的检测一下应用及时发现问题,解决问题。
现状
近期慢慢开始越来越多的线上用户反馈应用卡的问题,出现问题的页面主要集中在:
1、登录卡住,实际已经登录成功但是一直卡在登录的loading页面
2、进入直播间的页面卡住
3、进入个人主页卡住
出现问题的机型 基本都集中在iPhone 6上,虽说iPhone 6是属于比较旧的机型了,但是在用户中所占的比重还是挺多的(苹果的不作为导致大家都没有理由去换新手机了)。
听到用户反馈这个问题,其实第一感觉 对于2.3两个页面我们大概都能知道原因,因为界面比较复杂,而且要预加载部分信息,所以在较旧的设备上卡是正常的。对于登录页面其实我百思不得解。
现状就说到这里,下面开始干……
性能检测工具
对于iOS项目,苹果爸爸其实在Xcode中已经为我们提供了一套性能检测工具:
对于这些工具 可以做一个简单的分类:
可以根据自己的实际情况 去选择不同的工具,废话不多说,开干!!!
Time Profiler
根据我们的实际情况,首先是卡顿,所以我要知道 应用中的耗时操作到底在哪里,是否有一些耗时操作放到了主线程,导致应用的卡顿。
下面我们主要玩玩这个小东西:
选择正确的应用和正确的设备
温馨提示:应用必须是已安装的哦
开始检测
点击红色按钮我们就可以开始对我们选中设备和选中的应用进行检测了。
界面简单介绍
- 各个线程的采集数据汇总
- 点击1中的某一行,可以看到采集到的堆栈,注意2区域的右上角,可以选择隐藏系统的符号
- 可以选择关注的队列/CPU等。
- 可以用pinch手势来放大缩小时间范围,鼠标可以拖动选择一段区域
检测结果
额,顿时有种 裤子都脱了你给我看这个!!(问号脸)
正确展示检测信息
遇到这种事,一定要告诉自己:你一定不是第一个遇到这个问题的人。所以呢 谷歌一下 你就知道
原因:打包模式没有开启dSYM或者debug symbols
所以 将debug切换到 DWARF with dSYM File
下面 我们重新跑一次!
好像虽然有一些我比较熟悉的类出现,但是面对这样的提示,我依然是一脸懵逼呀!
筛选检测信息
Time Profiler
默认将检测的所有信息都返回给我们,所以,如果想快速的定位问题 我们需要正确的筛选这些信息。
在上图的位置处,Time Profiler 给我们这几个选项,首先来看看这几个选项是什么意思:
- Separate by State:线程分离,状态分开显示 ,例如:Running状态
- Separate by Thread:按线程分开进行分析。容易找出消耗资源的问题线程,特别是对于主线程,因为主线程要处理和渲染所有的接口数据及UI视图,当主线程受到阻塞性操作,一定会造成程序的卡顿,或停止响应。
- Invert Call Tree:反向显示调用树。把调用层级最深的方法显示在最上面,容易找到最耗时的操作。
- Hide System Libraries:隐藏缺失的符号。把干扰信息屏蔽掉,即把列表中因为系统架构,或DSYM文件缺失造成奇怪的十六进制的数值。
- Flatten Recursion:拼合递归。把同一递归函数产生的多条堆栈合并为一条。
- Top Functions:找到最耗时的函数或方法。
依据我们的情况可以选择 Separate by Thread
和 Hide System Libraries
结果分析
筛选之后 我们可以拿到上面的记过,对于卡顿的问题,一般是因为有一些操作应该放在子线程去做的,结果放到了主线程中,因此 我们把重点放在主线程上
在上面这张图中,我们就可以比较清晰的看到 我们在项目中书写的一些方法。每一行的前面,就是这一行代码对应的耗时时间。
现在我们需要操作一下手机,然后看一下出问题的这段时间,都有哪些耗时操作。
在分析耗时的时候 我们可以看到前面两列Weight
和 Self Weight
这两列表示总的耗时和当前行在总耗时中的比重,因此我们可以直接排除掉Self Weight
为0的行。
这样我们一层层的展开就可以找到耗时的具体方法了
如果层级太深,我们可以双击某一行进入一个新的页面,单独看这一行展开的内容
在这个页面 如果我们想定位到具体的代码,我们可以直接双击该行,就可以直接打开 对应耗时的那一行代码
这样我们就可以根据实际情况,针对出现问题的代码进行修改和优化!
另外 我们可以对页面中出现的多个耗时操作进行排序
耗时操作检测完成
通常很明显的页面卡顿都是因为将某些耗时操作放到了主线程中,解决方法也很简单,将一些复杂计算或者网络请求放到子线程中去执行。
当然,还有其他的页面会导致页面卡顿,比如,当界面有大量的shadow,mask或者有非常多的View/Layer,GPU渲染纹理和顶点的时候可能会有压力。
总结一下,页面卡顿的原因主要分为两大类:CPU瓶颈和GPU瓶颈。
所以Time Profiler
能做的只是对于CPU使用率的监控。对于GPU的监控 我们应该去是用Core Animation