App啓動優化

App啓動的三個階段:

  • main()函數執行前;
  • main()函數執行後;
  • 首屏渲染完成後。

main()函數執行前

  • 加載可執行文件
  • 加載動態鏈接庫
  • Objc運行時初始處理,相關類的註冊、category註冊、selector唯一性檢查等
  • 初始化,執行+load()方法、__attribute__((constructor))修飾的函數調用、創建c++靜態全局變量

此階段優化方案:

  • 減少動態庫加載 (可以將多個動態庫合併,非系統動態庫最多6個合爲一個)
  • 減少類、分類、方法(selector)的數量
  • 用+initialize方法和dispatch_once取代所有的ObjC的+load
  • 減少c++全局變量的數量

main()函數執行後
此階段是指main()函數開始執行 -> didFinishLaunchingWithOptions裏首屏渲染方法執行完成
注意首頁業務代碼是在首屏渲染完成前執行

  • 首屏相關基礎庫初始化
  • 首屏相關業務數據讀取和處理
  • 首屏渲染的大量計算

此階段優化方案

  • 各種初始化工作,不要都放到此階段裏面,會導致首屏渲染滯後。啓動必要初始化,首屏渲染必要初始化,可以放在此階段。其他的初始化放到對應功能使用之前。

首屏渲染完成後
此階段是指 didFinishLaunchingWithOptions 方法作用域內首屏渲染之後的所有方法執行完成

非首屏其他業務服務模塊的初始化

  • 監聽的註冊
  • 配置文件的讀取等
  • 此階段首頁信息已經顯示完成

此階段優化方案

  • 主要優化主線程耗時方法,滯後執行或者異步執行,因爲此階段已經顯示首頁,主要優化用戶的交互。

App啓動速度的監控
通過在工程的scheme中添加環境變量DYLD_PRINT_STATISTICS,設置值爲1,App啓動加載時Xcode的控制檯就會有pre-main各個階段的詳細耗時輸出。

另外兩種方法:

第一種方法:定時抓取主線程上的方法調用堆棧,計算一段時間裏各個方法的耗時
Time Profiler 就是採用這種方式。

注意點

定時間隔長則會漏掉某些耗時短的方法
定時間隔短,抓取堆棧的方法本身會頻繁調用,影響整體耗時
一般設置0.01秒,對整體耗時影響小,但是檢測的很多方法耗時就不準確了。不過整體耗時數據比較重要,單個耗時不準可以接受。
如果設置0.002秒基本所有方法都可以檢測,整體耗時就不準了。

第二種方法:對 objc_msgSend 方法進行hook來掌握所有方法的耗時
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章