移動端啟動速度
時間:2020-03-29 07:15:07 來源:互聯網 閱讀:-
本文摘要:一款App,啟動速度是最最大的門面,也是用戶接觸app的第一印象,試想,第一次進入app,就打不開,或者過了N秒才能進入主界面,會有多少用戶有耐心繼續使用下去。

一款App,啟動速度是最最大的門面,也是用戶接觸app的第一印象,試想,第一次進入app,就打不開,或者過了N秒才能進入主界面,會有多少用戶有耐心繼續使用下去。

所以這篇文章會從Android和iOS兩個維度,根據啟動機制的差異介紹一下啟動速度的優化方式。



Android


啟動分析

對于Android的啟動分析,有一張很經典的圖:

image.png

  • T0到T1:用戶點擊了圖標,這時候首先響應操作的并不是app,而是rom的Launcher,然后就是大家熟知的AMS和WMS操作,這塊講起來有些復雜,之后會放到一個單獨的文章中,而且這里的優化其實是app根本插不上手的,所以不是本文重點。在系統拉起進程之前,需要先顯示一個預覽窗口,這個是在app中配置的theme,如果theme是透明的,現在還是看到的桌面。這里不建議進行透明配置,會給用戶一個點擊延遲的錯覺。iOS在這里處理的很好,雖然機制不同,但是在點擊圖標后,會先去顯示Launcher畫面,這個是一個固定配置,所以交互感覺更友好一些。
  • T1到T2:進程創建完畢了,就要走Application了,然后根據布局等等顯示閃屏畫面(如果有閃屏的情況)
  • T2到T3:閃屏結束了,開始顯示首頁了,但是實際上從Application(T1)開始,我們可能需要注冊很多組件,或者加載很多三方庫,這些都是較為耗時的
  • T3到T4:進入了首頁,便是開始加載各類網絡請求,以及對應的一些彈窗界面(業務需求)

優化方式

如果看懂了上述流程,我們可以理出一些優化點:

閃屏優化

如果禁用了預覽窗口,那么用戶到T2才能看到閃屏,之前都是桌面,這個體驗是非常不好的,尤其是對于中低端機型,這時候可以加一個與閃屏界面相同的主題。

  1. 這塊可以對比一下今日頭條和小米有品(并無惡意,只是我的手機中這倆app是挨著的),點擊今日頭條,迅速顯示閃屏,小米有品是先白屏在進入閃屏,雖然時間上差距可以忽略,但是對于中低端機型會非常明顯(炫耀了一把我的高端手機)
  2. 另一種方式是,將閃屏和首頁合成一個Activity,減少一個Activity的耗時,微信這樣做后,據說減少了100ms,并未實操,感興趣的朋友可以試一下。

三方庫優化

上面提到了組件注入,以及三方庫加載,這個是一個耗時很高的地方,也是一個最大的優化點,合理安排業務,將一些不是馬上要用的三方庫放到后面再去加載?;蛘呤褂脩屑虞d的方式。

但是這里要特別注意一件事,之前遇到了一種情況,講一個三方庫變成了懶加載,但是由于使用的地方太多,一些case未回歸,導致個別地方使用的時候未加載成功,所以功能失效了。使用這種方式一定要切記回歸case

業務優化

優化業務,為什么說要優化業務呢,啟動的每一毫秒都很重要,很多app一啟動,會彈出N多彈窗,常見于各類電商軟件,這些都是需要預加載的,都是需要時間的,所以這里需要合理衡量業務,砍掉無用的預加載,放到首頁加載完成之后再去彈。

還有一些情況,如需要監聽首次啟動的各類廣播,或者其他類型的監聽器,當事件觸發回調,可能出現大量代碼并發。

當然還有其他類型的情況,都是業務太重導致的,這就需要梳理業務,讓啟動(重要的是首次啟動)變得更清晰一些。

還有根據部分業務需求,可能出現在首頁加載大的動畫,這類需求,需要根據機型進行降級,低端機型低端處理,高端機型高端處理。

線程優化

線程優化包括兩個方面,一是優化啟動的線程數,這主要是減少CPU的壓力。另一方面就是減少子線程和主線程交互時的一些block問題,比如雖然我們把耗時操作放到子線程了,但是主線程執行的一些任務可能等待子線程的鎖(或者以回調形式執行),這就尷尬了,盡量避免這種邏輯發生。之前在iOS時發生過類似的事情,啟動之后需要根據一個變量判斷后續執行,但是這個變量是在子線程賦值的,有時候還會出現同時讀寫的問題。

GC優化

啟動的過程中盡量避免大量的字符串操作,尤其是序列化,反序列化等等,防止出現較多的GC。這時候我們可以盡量復用一些對象,可以頻繁賦值,但是不要頻繁創建。

I/O優化

在負載過高的時候,I/O 性能下降得會比較快,一定要清楚啟動的時候進行了哪些I/O操作,讀了什么文件,進行了什么樣的網絡請求,請求回來什么樣的內容,大小是多少等等。如果文件大小內容都是固定的還好,但是可能出現內容不定的情況。如果xx聊天工具,啟動的時候需要加載聊天記錄,這個文件可能很大,可能很小,需要根據不同情況進行處理。

數據重排

這個思路是之前在網上看到的,感覺很新穎,也記錄下來了。這里要先介紹一下linux讀取文件的機制。Linux讀取文件會以block為單位,一次性在磁盤上讀取4kb的內容,并且放到Page Cache中,這時候我們進行讀取,實際不會發生真正的磁盤I/O。但是我們可能只有許多零碎的小文件,都是1K左右的,這時候我們可以考慮把數據進行重排,在同一時間需要用的數據放到一個文件中。只要4k以下,是可以一次讀取的,不會浪費磁盤I/O的時間。

類重排

這也是一個新穎的概念,我們可以通過重寫ClassLoader,看一下啟動的過程中類的加載順序,然后通過FaceBook提供的ReDex進行類重排,將啟動過程中用的類往前排。

啟動速度.png

iOS


啟動分析

iOS的啟動分析包含兩個部分,一部分是pre-main,一部分是main,這個分類很好理解。

  • main()執行前:加載可執行文件(.o文件)加載動態鏈接庫Objc 運行時的初始處理,包括 Objc 相關類的注冊,category的注冊,selector唯一性檢查執行+load方法,attribute((constructor)) 修飾的函數的調用,C++靜態全局變量
  • main()執行后,這個主要包括從main開始到appDelegatedidFinishLaunchingWithOptions中代碼執行完畢。從這里開始都是我們自己的代碼了,在這里一般是各類三方庫的初始化,配置文件讀寫,首頁加載等等。有的監測軟件,也會將main執行后的代碼以首屏開始加載為錨點,再進行分割,分成首屏渲染前和首屏渲染后。

優化方式

減少動態庫的加載

pre-main中有個重要的步驟就是加載動態庫,如果動態庫過多,可以將動態庫進行合并。非系統的動態庫,可以支持合并成一個動態庫。

減少類

減少加載啟動后不需要的類,有時候業務冗余,或者代碼年久失修,會有很多類其實不用了,但是仍然出現在工程中,再或者可能幾個類能夠合并成一個類。

+load優化

+load方法是在main函數之前調用的,遵從先父類后子類,先本類后列類別的順序調用,+initialize方法是在main函數之后調用的,+initialize方法遵從懶加載方式,只有在類或它的子類收到第一條消息之前被調用的.+initialize只調用一次,init可多次調用。所以少在類的+load方法里做事情,盡量把這些事情推遲到+initiailize

控制C++全局變量個數

這主要是針對在函數外生命的變量,盡量減少這樣的聲明

業務優化(與android相似)

優化業務,為什么說要優化業務呢,啟動的每一毫秒都很重要,很多app一啟動,會彈出N多彈窗,常見于各類電商軟件,這些都是需要預加載的,都是需要時間的,所以這里需要合理衡量業務,砍掉無用的預加載,放到首頁加載完成之后再去彈。

還有一些情況,如需要監聽首次啟動的各類廣播,或者其他類型的監聽器,當事件觸發回調,可能出現大量代碼并發。

當然還有其他類型的情況,都是業務太重導致的,這就需要梳理業務,讓啟動(重要的是首次啟動)變得更清晰一些。

還有根據部分業務需求,可能出現在首頁加載大的動畫,這類需求,需要根據機型進行降級,低端機型低端處理,高端機型高端處理。

線程優化(與android相似)

線程優化包括兩個方面,一是優化啟動的線程數,這主要是減少CPU的壓力。另一方面就是減少子線程和主線程交互時的一些block問題,比如雖然我們把耗時操作放到子線程了,但是主線程執行的一些任務可能等待子線程的鎖(或者以回調形式執行),這就尷尬了,盡量避免這種邏輯發生。之前在iOS時發生過類似的事情,啟動之后需要根據一個變量判斷后續執行,但是這個變量是在子線程賦值的,有時候還會出現同時讀寫的問題。

專注于首屏數據

之前的代碼中,有這樣的邏輯,在加載首屏的同時,還要加載第二屏的內容(TabBarViewController的第二個Tab),這個是沒有必要的,如果需要預加載,可以將預加載放到首屏加載完成,可交互之后再去執行。

配置文件讀取優化

只加載與首屏相關的內容,其他的配置內容可以放到首屏加載完成后去讀取。

充分利用TimeProfiler

在進行首屏數據加載的時候,有很多方法可能造成耗時較長,之前遇到過一個這樣的事情,首頁加載時間較長,使用TimeProfiler看了一下時間,主要集中在首頁圖片加載中,首頁有很多各式各樣的圖片,甚至于一些動畫,這個時候就要看看耗時主要在哪,比如,UIImage存在延遲解壓的問題。+imageNamed這個方法會在加載圖片之后立刻進行解壓,如果圖片過大過大,這個在首屏展示的時候肯定會有性能影響,所以可以考慮使用imageWithContentsOfFile進行異步加載。當然還有其它方法的耗時,需要根據情況進行優化。

三方庫優化

與Android類似,很多三方庫不一定要在初始化的時候進行加載,需要梳理各類三方庫的作用域,將不重要的三方庫,放到首屏的viewDidAppear中去加載。這里看似簡單,但是是需要認真梳理的,需要扣一下所有的三方庫的應用場景,延遲加載會有什么樣的影響。

iOS優化建議.png

總結

好了,大致就這些內容,里面很多方法,已經在實際工作中投入使用,還有一些,是對網上主流優化方法的整理,也打算進一步的試用,如果您有更好地方式,歡迎給我留言

(正文已結束)

推薦閱讀:風扇怎么折

免責聲明及提醒:此文內容為本網所轉載企業宣傳資訊,該相關信息僅為宣傳及傳遞更多信息之目的,不代表本網站觀點,文章真實性請瀏覽者慎重核實!任何投資加盟均有風險,提醒廣大民眾投資需謹慎!

安微11选五定位走势图 大乐透预测技巧 山东11选5人工稳定计划 基金配资 河南福彩快3今天预测 快3助手开奖结果 北京pk10预测网站 炒股票融资 股票指数下跌的含义 600779股票 青海十一选五开奖历史