当用户使用一款IOS App,打开App界面时,过长的等待时间会使用户陷入焦虑,对用户的留存率产生不良影响,虽然精致的启动页能对等待焦虑有一定的缓解作用,但是最好还是尽可能地减少App的启动时间。最近参与开发了一款IOS App,为了达到减少App启动时间的目的,我们首先明确了影响IOS App启动时间的因素,并做了相应的优化。

完整的App启动过程包括两部分,第一部分称是在main()函数执行之前完成的(下文描述为过程一);第二部分从main()函数执行开始到第一个界面渲染完成(下文描述为过程二)。

过程一

测算时间

Xcode提供了输出pre-main耗时的配置,

通过在Edit Scheme -> Arguments -> Environment Variables -> +添加name为DYLD_PRINT_STATISTICS,value为YES的环境变量。

当Xcode运行App时,会在console中输出pre-main的总耗时,以下为次元仓的输出数据:

Total pre-main time: 773.69 milliseconds (100.0%)

dylib loading time: 143.95 milliseconds (18.6%)

rebase/binding time: 130.67 milliseconds (16.8%)

ObjC setup time: 80.49 milliseconds (10.4%)

initializer time: 418.36 milliseconds (54.0%)

slowest intializers :

libSystem.B.dylib : 19.92 milliseconds (2.5%)

libBacktraceRecording.dylib : 46.24 milliseconds (5.9%)

libglInterpose.dylib : 148.03 milliseconds (19.1%)

libMTLInterpose.dylib : 31.94 milliseconds (4.1%)

CYC : 201.71 milliseconds (26.0%)

分析优化

测算时间中的数据中主要包括了4部分数据:

1. dylib loading time:动态库加载耗时

* 动态库的加载数量越多,加载耗时越长,可以通过合并多个动态库或者使用静态库代替进行优化

* 使用dlopen()懒加载动态库,这个方法相对比较复杂,如非必要不鼓励使用

2. rebase/binding time:指针修正耗时

* 尽可能少地添加Objective-C的metadata(类、category和Selector)的数量,使Rebase/binding过程中指针修正的时间减少

* 尽可能少地使用C++虚函数,虚函数的加载也需要进行指针修正

3. ObjC setup time:

* 耗时与Objective-C的metadata(类、category和Selector)的数量和更新Non Fragile ivars偏移值相关,优化方式与rebase/binding time类似。

4. initializer time:调用Objective-C的+load方法进行初始化的耗时

* 与ObjC的+load方法执行时间相关,通过把+load方法替换为+initialize方法,延迟初始化的执行

过程二

执行顺序

App启动顺序

1. App被用户显性启动或者被系统隐性启动了。

2. 作为App程序入口的main()函数会调用UIApplicationMain()函数。

3. UIApplicationMain()函数创建UIApplication对象、App delegate和main runloop。

4. UIKit从Deployment Info->Main interface设置的main storyboard或者xib中加载App的默认界面

5. UIKit调用App delegate的-Application:willFinishLaunchingWithOptions: 方法.

6. UIKit调用App delegate相关的代理方法重新获取缓存状态。

7. UIKit调用App delegate的-Application:didFinishLaunchingWithOptions:方法.

8. 启动过程完成。

分析优化

在开发过程中我们可以针对优化步骤4、7进行优化

* 针对步骤4,main storyboard或者xib的需要加载的数据量大,尽可能地把Deployment Info->Main interface的设置去掉,需要加载root controller的时候再通过-Application:didFinishLaunchingWithOptions:方法进行加载,并且root controller最好是纯代码实现,延迟subview的加载。

* 针对步骤7,需要针对具体业务分析是否必须在-Application:didFinishLaunchingWithOptions:中完成。比如说日志、统计、推送等业务,是必须在App完成启动前就配置好的;比如说首页数据更新、获取广告信息等业务则可以延迟到启动完成后再执行。

总结

以上是我在工作中总结的App启动时间优化方法,在实际开发中,我们需要根据具体的App架构和业务选择相应的优化。还可以用工具针对App启动时间进行监测,在这里,推荐“友盟+U-APM应用性能监控平台”这款工具,它可以辅助开发者实时监测App后台出现的问题,以及App启动时间的问题,找到问题从而方便开发人员进行修复并优化。通过轻量级的集成接入即可拥有实时、可靠、全面的应用崩溃、ANR、自定义异常等捕获能力,及卡顿、启动分析、内存分析、网络分析等性能监测能力。可助更多APP开发同学从中获益。

IOS App 启动时间优化实战相关推荐

  1. struts启动时加载_iOS优化篇之App启动时间优化

    原文:橘子不酸丶http://www.zyiner.com/article/5 前言 最近由于体验感觉我们的app启动时间过长,因此做了APP的启动优化.本次优化主要从三个方面来做了启动时间的优化,m ...

  2. iOS app性能优化的那些事

     iPhone上面的应用一直都是以流畅的操作体验而著称,但是由于之前开发人员把注意力更多的放在开发功能上面,比较少去考虑性能的问题,可能这其中涉及到objective-c,c++跟lua,优化起来相对 ...

  3. iOS App 启动优化

    简介: 作为程序猿来说,"性能优化"是我们都很熟悉的词,也是我们需要不断努⼒以及持续进⾏的事情:其实优化是⼀个很⼤的课题,因为细分来说的话有⼤⼤⼩⼩⼗⼏种优化⽅向 ,但是切忌在实际 ...

  4. App 启动时间优化方法详解

    用户希望APP 能够快速响应并加载. 一个启动速度慢的APP 不符合用户期望,可能会令用户失望,并且可能会导致用户对您的应用程序评价不佳,甚至会卸载你的应用. 本文将讨论如何优化应用的启动时间,首先我 ...

  5. iOS app性能优化

    instruments   在iOS上进行性能分析的时候,首先考虑借助instruments这个利器分析出问题出在哪,不要凭空想象,不然你可能把精力花在了1%的问题上,最后发现其实啥都没优化,比如要查 ...

  6. Android 性能优化---(8)APP启动时间优化指南

    本文可以帮助你优化应用的启动时间:首先描述应用启动过程的内部机制:然后讨论如何分析启动性能:最后,列举了一些常见的影响启动时间的问题,并就如何解决这些问题给出一些提示. 第 1 部分:启动过程内部机制 ...

  7. Linux 启动时间优化实战,2.41 秒启动应用!

    来源于:老吴嵌入式 今天看了一个关于启动优化的讲座,简单总结一下. 本文的目标是尝试一些比较简单有效的方法,并不会覆盖所有的优化技巧. 目标系统 硬件: Beagle Bone Black (Cort ...

  8. iOS APP 瘦身实战

    前言 app为什么要瘦身,无非是下面几个情况, 第一,产品或者运营觉得包体积过大了! 第二,对技术的追求,也给自己涨点绩效! 第三,面试被问到了..... 哈哈 不管哪种情况吧,要瘦身就好好玩下吧. ...

  9. iOS app的启动优化

    返回上级目录:iOS面试专题一 文章目录 1.冷启动分为两个阶段:main函数之前和之后 2.pre-main阶段 2.1 Load dylibs image:加载动态库 2.2 Rebase/Bin ...

最新文章

  1. div.php织梦自定义表判断不能为空,织梦自定义表单字段为必填项的教程
  2. 【LDA学习系列】LDA-Python库
  3. CG CTF WEB 文件包含
  4. 列举在Web前端开发中经常会设置的特殊样式!
  5. Mac 编译报错 symbol(s) not found for
  6. openpyxl 读写 excel
  7. swiper链接href无效
  8. 2 RepMLP:卷积重参数化为全连接层进行图像识别 (Arxiv)
  9. python中构造函数可以重载吗_python中的函数重载了吗?
  10. 反射 java 例子 get_Java反射实例
  11. php跳转方式带rere_PHP利用REFERER根居访问来地址进行页面跳转
  12. 将String 转换为byte[]数组
  13. Tomcat Session Clustering
  14. 捕鱼分鱼、出售鱼、平分七筐鱼
  15. linux内核编译串口驱动,ARM Linux下安装CH341串口驱动
  16. Python 打印九九乘法表
  17. C# RichTextBox 制作文本编辑器
  18. 使用Java实现给QQ邮箱发送验证码
  19. Kmplayer音频设置
  20. C 不常见的一些晦涩语法

热门文章

  1. 计算机专业是绩点重要,东北大学13级绩点排名-计算机专业
  2. RK3399平台开发系列讲解(内核驱动外设篇)6.27、加密芯片支持(一)驱动支持
  3. python给图片加上白边,使图片达到所需的纵宽比
  4. Greenplum数据库的安装
  5. 服务器性能测试,导热膏选择
  6. 小程序弹窗改造自定义
  7. 充电宝能用多长时间?充电宝怎么用寿命长
  8. 使用PICT生成成对组合进行组合覆盖测试,以及PICT和正交表的比较
  9. 下单购买商品启用积分抵扣功能
  10. PVE 7 虚拟化 Intel UHD630 WIN10 UEFI 关机后 无法启动问题 显卡无法安装问题 intel 显核驱动 错误代码8 问题 解决方案