ezbuy iOS APP启动时间优化

来源: APP研发(上海) 团队 - 许赟ios

摘要

(App总启动时间)T = (main()以前的加载时间)T1 + (main()以后的加载时间)T2swift

T1 = 系统dylib(动态连接库)和自身App可执行文件的加载;bash

T2 = main方法执行以后到AppDelegate类中的- (BOOL)Application:(UIApplication *)Application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法执行结束前这段时间,主要是构建第一个界面,并完成渲染展现。app

注: 如下测试时间如无特殊说明, 均在 macOS Mojave10.14.3, Xcode10.2.1, iPhone6 plus, iOS12.3.1, ezbuy-UAT的环境下!!!异步

一. T1(main函数以前的加载时间)

T1能够经过在EditScheme中添加 DYLD_PRINT_STATISTICS 这个环境变量来查看.函数

图片描述
注意为了接近真实状态, 最好是把 Bulid Configration 改为 Release, 而且链接真机而不是模拟器来查看.

ezbuy-UAT pre-main时间图: 性能

图片描述

pre-main阶段如何优化

在preMain阶段由于涉及到底层, 目前能作的工做很少.最可能是删除一些Pod中再也不用到的库. 若是后续有人对这部分的优化比较感兴趣能够移步这里测试

二. (main()以后的加载时间)T2

这段时间的衡量在项目中打印便可, 由于swift把main函数和appDelegate合并成了一个文件, 因此项目中找不到main函数的入口, 但咱们能够本身建立一个:优化

1 建立一个名为main.swift的文件, 在文件中写入如下代码(swift5):动画

import Foundation
import UIKit

var START_TIME:CFAbsoluteTime = CFAbsoluteTimeGetCurrent()
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))
复制代码

2 到APPDelegate文件中,注释掉 @UIApplicationMain

3 在 didFinishLaunchingWithOptions 方法 return true 前面加上如下代码

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
	/*...*/

   	NSLog("*** App Launched in: %f sec", CFAbsoluteTimeGetCurrent() - START_TIME)
    
    return true
  }
复制代码

目前运行项目获得的结果是

图片描述

main()阶段如何优化

这一阶段的优化主要是减小 didFinishLaunchingWithOptions 方法里的工做,在 didFinishLaunchingWithOptions方法里,咱们会建立应用的window,指定其rootViewController,调用windowmakeKeyAndVisible方法让其可见。因为业务须要,咱们会初始化各个二方/三方库,设置系统UI风格,检查是否须要显示引导页、是否须要登陆、是否有新版本等,因为历史缘由,这里的代码容易变得比较庞大,启动耗时难以控制。 因此,知足业务须要的前提下,didFinishLaunchingWithOptions在主线程里作的事情越少越好。在这一步,咱们能够作的优化有:

  1. 梳理各个二方/三方库,找到能够延迟加载的库,作延迟加载处理,好比放到首页控制器的viewDidAppear方法里。
  2. 梳理业务逻辑,把能够延迟执行的逻辑,作延迟执行处理。好比检查新版本、注册推送通知等逻辑。
  3. 避免复杂/多余的计算。
  4. 避免在首页控制器的viewDidLoadviewWillAppear作太多事情,这2个方法执行完,首页控制器才能显示,部分能够延迟建立的视图应作延迟建立/懒加载处理。
  5. 采用性能更好的API。
  6. 首页控制器用纯代码方式来构建。

三. ezbuyApp启动时间优化作的工做

1) pre-main()阶段

podfile中删掉MenuItemKit, 由于MenuItemKit时间自己加载就只有30ms左右(见上面pre-main时间图), 已经预料到时间应该并没有显著差别 优化前pre-main十次平均时间 1.29s , 优化后 1.33s

2) main()方法以后

1 把didFinishLaunchingWithOptions中能放到异步线程执行的代码都放到异步线程中. 2 把app启动动画时间从0.5s缩短到0.2s

  1. main函数执行时到didFinishLaunchingWithOptions结束,运行10次的平均时间: 优化前 3.56 , 优化后 1.08
  2. main函数执行时到ShopHomeDefaultViewController viewDidAppear 方法结束时,运行10次的平均时间: 优化前 4.85 , 优化后2.07

补充: 下午由于删掉MenuItemKit从新运行了十次, 优化后的平均数据分别为 2.36` , 多是手机自己因为下午资源占用比较多,因此时间较上午长

参考文章: iOS App Launch time analysis and optimizations Slow App Startup Times 今日头条iOS客户端启动速度优化 阿里数据iOS端启动速度优化的一些经验 Get your app launch time with Swift How to subclass UIApplication using UIApplicationMain

相关文章
相关标签/搜索