当 APP 开发到了一定的阶段,性能优化这个话题就会被提起,性能优化的途径有很多,不过通常都会使用到 Apple 官方提供的 Instruments 工具。这个博客我就利用 raywenderlich 的一个代码案例 Catstagram 来介绍 Time Profiler 这个 Instrument 的使用(详见参考部分)。
性能优化的常用步骤
在对 APP 进行性能优化的过程中,我们肯定是会针对一些 APP 存在的问题来针对性优化的,比如 APP 启动速度慢,大数据量列表滑动卡顿,列表图片加载过程卡顿 。第一步决定了要优化的点之后。第二步就是使用 Instruments 来分析 APP 了 ,值得注意的是 Instruments 并不能帮我们完成优化,只是帮助我们分析 APP 运行过程的各种性能参数。第三步就是根据 Instruments 分析结果做对应的假设,假设是我们的某段代码导致了性能问题。第四步就是修改导致性能问题的某段代码。修改完之后呢?当然是要验证修改的效果了,所以第五步是验证修改效果,若是达不到效果,那么就从第一步继续重新开始。在这个过程中最好使用性能最差最烂的设备,不要使用性能太好或者性能一般的设备来测试。
Time Profiler 界面介绍
快捷键 command + I 打开 Instruments 界面,选择 Time Profiler 模板
每个 Instrument 的界面轮廓都是相似的,都是分为 Toolbar , Timeline pane , Detail pane , Inspector pane 这个模块。
Toolbar 各部分的名称
Timeline pane , Detail pane , Inspector pane 这几个模块的内容和使用的 Instrument 关系比较大,下图是使用 Time Profiler 的各模块细节。对于 Time Profiler 来说,它的 Timeline pane 默认展示的是 CPU 的使用,Detail pane 默认展示的是 APP 中各个线程的方法调用,Inspector pane 展示的是被选中的 Symbol 的详细信息 。
对于界面的详细介绍可以参考 Apple 的官方文档 https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html#//apple_ref/doc/uid/TP40004652-CH3-SW1 ,该文档对Instruments 各个工具界面以及基本使用方法做了详细介绍。
Time Profiler 使用
下图是 APP 的一个截图,该 APP 是一个图片列表。
第一步判断问题可能出现在哪里,因为 APP 是一个图片列表,所以优化的时候优先考虑图片加载和显示方面的问题。
第二步使用 Instruments 来分析 APP。
运行 Time Profiler Instrument 并对 APP 做了运行情况录制之后,按住鼠标左键并拖动,截取 CPU 使用率较高的一段运行时间进行分析。
第三步根据 Instruments 分析结果做对应的假设。
运行时间的截取确定后,可以在 Detail pane 查看运行过程中的一些 APP 细节,也可以从 Inspector pane 查看更详细的运行信息 ,从下面的截图中可以看出一些异常状况。
- 从 Detail pane 中可以看出主线程占用了 67.8% 的 CPU 时间
- 从 Detail pane 中可以看出主线程的工作基本都是在图片处理操作
- 从 Inspector pane 可以看出图片的解码操作是在主线程完成
从上面的分析结果中,可以提出一个假设,那就是 Cell 的图片加载方法存在问题。
第四步修改代码
由于是演示 Time Profiler 的使用,所以这里只是简单过一下代码。
找到设置图片的代码位置,该代码是在主线程给一个 UIImageView 对象设置 UIImage 对象,图片的解码操作是在主线程中进行的。
代码改进后是这样的,创建一个自定义 View 叫做 AsyncImageView,在这个View里面封装了图片的解码操作,这个解码操作在非主线程执行。
第五步代码修改完成之后,接下来就是需要验证修改是否起作用了。继续使用 Instruments 的 Time Profiler 工具验证。老样子,还是运行 Time Profiler Instrument 并对 APP 做了运行情况录制之后,截取了 CPU 使用率较高的一段运行时间进行分析。可以发现以下情况
- 从 Detail pane 中可以看出主线程占用了 20.3% 的 CPU 时间
- 从 Detail pane 中可以看出非主线程占据了较大的 CPU 时间
- 从 Inspector pane 可以看出图片处理操作发生在非主线程
总结
从结果可以看出,优化的点是对的,代码改动是生效的。为了让界面滑动更顺畅,我们通常会将部分工作从主线程转移到非主线程来,以保证主线程不卡顿。Time Profiler 这个 instrument 帮助分析 APP 的运行情况,通过分析这个 instrument 的结果,我们可以做出优化决策,然后实现这个决策并验证,最终实现我们的需求。
参考
这篇文章是我看了 raywenderlich 的 Practical Instruments 课程产生的一个笔记,主要是介绍 Time Profiler 这个 instrument 的使用思路,代码案例均来自于这个课程,感谢 raywenderlich 这个超级棒的平台。随着 Xcode 版本的更新,instruments 也是在不断的发生变化,但是整个 instruments 的使用思路是不变的,关于新增的变化可以参考 Apple 的官方 instruments 文档,里面也有很多关于 instruments 的使用细节
raywenderlich 的 Practical Instruments 课程 https://videos.raywenderlich.com/courses/74-practical-instruments/lessons/3
Apple 的官方 instruments 文档https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html#//apple_ref/doc/uid/TP40004652-CH3-SW1
图片处理技巧
https://developer.apple.com/videos/play/wwdc2014/419/