iOS 性能优化方案

297 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

启动优化

冷启动(从零开始的启动)

冷启动可以分为三个阶段

Main函数执行前
  • 加载可执行文件(mach-o文件
  • 加载动态链接库,进行rebase指针调整和bind符号绑定
  • Objc运行时的初始化处理,包括Objc相关类的注册category注册selector唯一性检查
  • 初始化,包括执行了+load()方法、attribute((constructor))修饰的函数调用、创建C++静态全局变量

优化方案

  • 减少动态库加载。每个库本身都有依赖关系,苹果公司建议使用更少的动态库,并且建议在使用动态库的数量较多时,尽量将多个动态库进行合并。数量上,苹果公司建议最多使用 6 个非系统动态库。
  • 减少加载启动后不会去使用的类或者方法
  • +load() 方法里的内容可以放到首屏渲染完成后再执行,或使用 +initialize() 方法替换掉。 因为,在一个+load() 方法里,进行运行时方法替换操作会带来 4 毫秒的消耗。不要小看这 4 毫秒,积少成多,执行 +load() 方法对启动速度的影响会越来越大
  • 控制 C++ 全局变量的数量
Main函数执行后

主要是指main()函数执行开始,到AppdelegatedidFinishLaunchingWithOptions方法里首屏渲染相关方法的执行

  • 首屏初始化所需要配置文件的读写操作
  • 首屏列表大数据的读取
  • 首屏渲染的大量计算

优化方案

从功能上梳理出哪些是首屏渲染必要的初始化功能,哪些是 App 启动必要的初始化功能,而哪些是只需要在对应功能开始使用时才需要初始化的。梳理完之后,将这些初始化功能分别放到合适的阶段进行。

首屏渲染完成

从渲染完成时开始,到 didFinishLaunchingWithOptions 方法作用域结束时结束

优化方案

  • 功能级别优化
    main() 函数开始执行后到首屏渲染完成前只处理首屏相关的业务,其他非首屏业务的初始化、监听注册、配置文件读取等都放到首屏渲染完成后去做
  • 方法级别去优化
    我们需要进一步做的,是检查首屏渲染完成前主线程上有哪些耗时方法,将没必要的耗时方法滞后或者异步执行。通常情况下,耗时较长的方法主要发生在计算大量数据的情况下,具体的表现就是加载、编辑、存储图片和文件等资源

热启动

  • App在内存中,在后台存活着,再次点击图标进入App

APP启动的监控手段

  • 1、定时抓取主线程上的方法调用堆栈,计算一段时间里各个方法的耗时
  • 2、对 objc_msgSend 方法进行 hook 来掌握所有方法的执行耗时。