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

相關文章
相關標籤/搜索