美文网首页iOS知识点面试
iOS App 启动时间优化

iOS App 启动时间优化

作者: Don_He | 来源:发表于2018-04-21 12:55 被阅读377次

在用户打开App的时候,过长的等待时间会使用户陷入等待焦虑,对用户留存率产生不良影响,虽然精致的启动页能对等待焦虑有一定的缓解作用,但是最好还是尽可能地减少App的启动时间。

为了达到减少App启动时间的目的,我们首先需要明确影响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方法,延迟初始化的执行

##过程二

###执行顺序

图1 App启动顺序

![The app launch and initialization sequence](https://docs-assets.developer.apple.com/published/52c7b459e7/76e68c08-6b09-4bac-8a00-44df7a097a43.png)

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架构和业务选择相应的优化。之后会继续补充完善,欢迎有兴趣的朋友讨论赐教。

##相关链接

[Optimizing App Startup Time](https://developer.apple.com/videos/play/wwdc2016/406/)

[Responding to the Launch of Your App](https://developer.apple.com/documentation/uikit/core_app/managing_your_app_s_life_cycle/responding_to_the_launch_of_your_app?language=objc)

相关文章

网友评论

    本文标题:iOS App 启动时间优化

    本文链接:https://www.haomeiwen.com/subject/hzmckttx.html