Just My Life & My Work

[iOS] APP啟動時間優化

APP啟動時間測量後,接下來要做APP啟動時間優化,這一部份開發者能夠干涉嗎?其實是可以的!

我們可以分兩部分優化如上圖,pre-main time和loading time

一、APP啟動過程

1.解析Info.plist

  • 加載相關信息,例如如閃屏
  • 沙箱建立、權限檢查

2.Mach-O加載

  • 如果是胖二進製文件,尋找合適當前CPU類別的部分
  • 加載所有依賴的Mach-O文件(遞歸調用Mach-O加載的方法)
  • 定位內部、外部指針引用,例如字符串、函數等
  • 執行聲明為__attribute__((constructor))的C函數
  • 加載類擴展(Category)中的方法
  • C++靜態對象加載、調用ObjC的+load 函數

3.程序執行

  • 調用main()
  • 調用UIApplicationMain()
  • 調用applicationWillFinishLaunching

二、影響APP啟動性能的因素

1. main()函數之前耗時的影響因素

  • 動態庫加載越多,啟動越慢。
  • ObjC類越多,啟動越慢
  • C的constructor函數越多,啟動越慢
  • C++靜態對象越多,啟動越慢
  • ObjC的+load越多,啟動越慢

實驗證明,在ObjC類的數目一樣多的情況下,需要加載的動態庫越多,App啟動就越慢。同樣的,在動態庫一樣多的情況下,ObjC的類越多,App的啟動也越慢。需要加載的動態庫從1個上升到10個的時候,用戶幾乎感知不到任何分別,但從10個上升到100個的時候就會變得十分明顯。同理,100個類和1000個類,可能也很難查察覺得出,但1000個類和10000個類的分別就開始明顯起來。

優化Dylib Loading前

優化Dylib Loading後

同樣的,盡量不要寫__attribute__((constructor))的C函數,也盡量不要用到C++的靜態對象;至於ObjC的+load方法,似乎大家已經習慣不用它了。任何情況下,能用dispatch_once()來完成的,就盡量不要用到以上的方法。

優化Rebase/Binding前

優化Rebase/Binding後

2. main()函數之後耗時的影響因素

main()函數開始至didFinishLaunchingWithOptions結束,我們統一稱為main()函數之後的部分。

  • 執行main()函數的耗時
  • 執行didFinishLaunchingWithOptions的耗時
  • rootViewController及其childViewController的加載、view及其subviews的加載

3. didFinishLaunchingWithOptions的耗時

其實didFinishLaunchingWithOptions方法裡我們一般都有以下的邏輯:

  • 初始化第三方SDK
  • 配置APP運行需要的環境,比如rootViewController加載
  • 自己的一些工具類的初始化

三、制定優化目標

分為四個部分:

  1. main()函數之前
  2. main()函數之後至didFinishLaunchingWithOptions完成
  3. App完成所有本地數據的加載並將相應的信息展示給用戶
  4. App完成所有聯網數據的加載並將相應的信息展示給用戶

四、優化方案

1. main()函數之前的優化

  1. 移除不需要用到的動態庫。
  2. 移除不需要用到的類。
  3. 合併功能類似的類和擴展(Category)。
  4. 壓縮資源圖片。
  5. 減少load 方法中執行的代碼。

2. main()函數之後至didFinishLaunchingWithOptions完成的優化

這一步主要優化didFinishLaunchingWithOptions方法中的代碼和rootViewController加載的優化。

  1. didFinishLaunchingWithOptions優化
    對於didFinishLaunchingWithOptions,這裡面的初始化是必須執行的,但是我們可以適當的根據功能的不同對應的適當延遲啟動的時機。對於我們項目,我將初始化分為三個類型:
  • 日誌、統計等必須在APP 一起動就最先配置的事件
  • 項目配置、環境配置、用戶訊息的初始化、推送、IM等事件
  • 其他SDK 和配置事件

對於第一類,由於這類事件的特殊性,所以必須第一時間啟動,仍然把它留在didFinishLaunchingWithOptions裡啟動。第二類事件,這些功能在用戶進入APP主體的之前是必須要加載完的,所以我們可以把它放在第二批,也就是用戶已經看到廣告頁面,再進行廣告倒計時的時候再啟動。第三類事件,由於不是必須的,所以我們可以放在第一個界面渲染完成以後的viewDidAppear方法裡,這裡完全不會影響到啟動時間。

  1. rootViewController加載優化
    這個只能看具體的邏輯和業務了,盡量把不必要的業務邏輯和網絡請求等延後加載。

以上是對岸朋友精心翻譯並詮釋WWDC 2016 406 Optimizing App Startup Time課程,講到底層我就頭痛,只要做工具的高手能處理好,我便能安心發揮創造力來開發App,若真有需要的話就可以來做啟動優化~

參考:iOS性能優化- APP啟動時間優化iOS App啟動時間優化原理iOS應用啟動性能優化資料

廣告

Comments on: "[iOS] APP啟動時間優化" (1)

  1. […] 接下來我們來研究如何優化App啟動時間吧:)~ […]

隨意留個言吧:)~

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

標籤雲

%d 位部落客按了讚: