iOS-底层原理 34:启动优化(二)优化建议

启动

启动的过程一般是指从用户点击app图标开始到AppDelegate 的didFinishLaunching方法执行完成为止,其中,启动也分为冷启动热启动

  • 冷启动:第一次打开app或app被杀死后重新打开叫冷启动(走didFinishLaunchWithOptions方法)

  • 热启动:app在后台且存活的状态下,再次打开app叫热启动(不走didFinishLaunchWithOptions方法)

而我们这里所说的启动优化,一般是指冷启动情况下的,这种情况下的启动主要分为两部分:

  • T1 :pre-main阶段,即main函数之前,操作系统加载App可执行文件到内存,执行一系列的加载&链接等工作,简单来说,就是dyld加载过程

  • T2:main函数之后,即从main函数开始,到Appdelegate 的didFinishLaunching方法执行完成为止,主要是构建第一个界面,并完成渲染

所以,T1+T2的过程 就是 从用户点击App图标到用户能看到app主界面的过程,即需要启动优化的部分

pre-main阶段的优化

通过Edit scheme --> Run--> Arguments添加环境变量DYLD_PRINT_STATISTICS,值设为1

运行程序,打印出如下数据,这些属于main函数之前的时间,也就是pre-main

Total pre-main time: 726.83 milliseconds (100.0%)
         dylib loading time:  39.36 milliseconds (5.4%)
        rebase/binding time:  50.96 milliseconds (7.0%)
            ObjC setup time:  15.55 milliseconds (2.1%)
           initializer time: 620.94 milliseconds (85.4%)
           slowest intializers :
             libSystem.B.dylib :   6.22 milliseconds (0.8%)
    libMainThreadChecker.dylib :  34.21 milliseconds (4.7%)
          libglInterpose.dylib : 416.45 milliseconds (57.2%)
                       Ebusbar : 291.12 milliseconds (40.0%)
Total pre-main time

整个pre-main花费的时间

dylib loading time

动态库的加载时间

优化方案: 我们主要是对自己调用的第三方动态库优化,苹果建议自定义的动态库不要超过6个,我们尽量减少使用自定义的动态库或者合并动态库

rebase/binding time
  • rebase:偏移修正
    任何一个app生成的二进制文件,在二进制文件内部所有的方法、函数调用,都有一个地址,这个地址是在当前二进制文件中的偏移地址。一旦在运行时刻(即运行到内存中),每次系统都会随机分配一个ASLR(Address Space Layout Randomization,地址空间布局随机化)地址值(是一个安全机制,会分配一个随机的数值,插入在二进制文件的开头),例如,二进制文件中有一个 test方法,偏移值是0x0001,而随机分配的ASLR是0x1f00,如果想访问test方法,其内存地址(即真实地址)变为 ASLR+偏移值 = 运行时确定的内存地址(即0x1f00+0x0001 = 0x1f01)

  • binding:绑定
    例如NSLog方法,在编译时期生成的mach-o文件中,会创建一个符号!NSLog(目前指向一个随机的地址),然后在运行时(从磁盘加载到内存中,是一个镜像文件),会将真正的地址给符号(即在内存中将地址与符号进行绑定,是dyld做的,也称为动态库符号绑定),一句话概括:绑定就是给符号赋值的过程

ObjC setup time

这一步做的主要操作就是类的加载,分类的合并,类越多越耗时

优化方案:合并或者删减一些OC类,关于清理项目中没用到的类,使用工具AppCode代码检查功能,查到当前项目中没有用到的类如下,清除一些没用的静态变量,清除一些没有用到的方法

initializer time

执行load和构造函数的耗时

优化方案:将不必须在+load方法中做的事情延迟到+initialize中,尽量不要用C++虚函数

main函数阶段的优化

在main函数之后的didFinishLaunching方法中,主要是执行了各种业务,有很多并不是必须在这里立即执行的,这种业务我们可以采取延迟加载,防止影响启动时间

main函数阶段的优化建议主要有以下几点:

  • 减少启动初始化的流程,能懒加载的懒加载,能延迟的延迟,能放后台初始化的放后台,尽量不要占用主线程的启动时间

  • 优化代码逻辑,去除非必须的代码逻辑,减少每个流程的消耗时间

  • 启动阶段能使用多线程来初始化的,就使用多线程

  • 尽量使用纯代码来进行UI框架的搭建,尤其是主UI框架,例如UITabBarController。尽量避免使用Xib或者SB,相比纯代码而言,这种更耗时

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容