App運行速度分析以及初步優化方案

App運行速度分析以及初步優化方案

一、 App運行速度分析

(1)硬件約束

CPU主頻,多核;

CPU主頻決定手機的運算速度,多核則更多體現在併發任務方面。

內存:運存與內存(RAM+ROM)

圖1-1 移動端內存示例圖

運存是指手機運行程序時的內存,也叫RAM簡稱運存;RAM越大,手機可運行的APP應用程序越多,運行越流暢,目前RAM基本是2GB夠用,3GB流暢,4GB極佳。

內存是指手機的存儲控件,也叫ROM;ROM越大,手機儲存的文件空間越多,目前ROM基本是16GB,32GB,64GB;ROM不影響手機的運行速度。

當運存(RAM)匱乏時,運行大型APP會出現卡頓、黑屏甚至出現暫時性卡死狀態。

在運存不夠時可以採取手動關閉後臺不必要的程序進行釋放,或者通過手機管理軟件進行內存釋放,例如手機管家、手機安全衛士等。


(2)網絡環境影響以及服務器接口環境

網絡狀況直接影響業務型APP的體驗,例如用戶登陸業務;登陸時手機端需要向服務器發送用戶的登錄名及密碼等信息,服務器進行信息覈對後返回登陸狀態指令,手機端接收到返回信息進行業務跳轉。登陸業務只需要進行一次接口調用,在網絡和服務器環境都理想的情況下,http三次握手時間可以控制在1秒以內。綜合考慮手機端網絡以及服務器環境,登陸控制在2.5秒內是可以被用戶接受的。

手機端針對網絡環境可採取相應的緩存策略以降低服務器的頻繁訪問,從直觀上提高頁面響應速度。根據業務級別提供相對可靠的有損服務,可採用懶加載、延遲異步加載等方式降低服務器壓力。

對於服務器可採用緩存服務器、分佈式服務器、反向代理等方式進行數據提供業務,對於圖片、視頻等媒體資源採用CDN進行加速。服務器端的優化性能提高率遠大於手機端優化的提高率。

(3)View的繪製過程

Measure(計算) ->  Layout(定位)  -> Draw(繪製)

整個View樹的繪圖流程是在ViewRoot.java類的performTraversals()函數展開的,函數做的執行過程可簡單概況爲根據之前設置的狀態,判斷是否需要重新計算視圖大小(measure)、是否重新需要安置視圖的位置(layout)、以及是否需要重繪(draw),其框架過程如下:


圖 1-2 View繪製流程示例圖

View的繪製時間可以利用hierarchyviewer工具進行查看。


圖1-3 hierarchyviewer示例圖

上圖Measure爲0.089ms,Layout爲0.115ms,Draw爲1.088ms,該view的繪製總耗時爲1.292ms。

(4)16ms原則

目前大多數手機的屏幕刷新頻率是60hz,如果在1000/60=16.67ms內沒有辦法把這一幀的任務執行完畢,就會發生丟幀的現象。丟幀越多,用戶感受到的卡頓情況就越嚴重。16ms時間很短,身爲一名應用開發者,爲了讓用戶有更好的體驗,應該要充分利用這16ms,確保刷新一幀的時候在16ms內。


1-4 UI刷新示例圖

如果你的某個操作花費時間是24ms,系統在得到VSYNC信號的時候就無法進行正常渲染,這樣就發生了丟幀現象。那麼用戶在32ms內看到的會是同一幀畫面。


1-5丟幀示例圖

優化16ms問題可以通過儘可能減少過度繪製,減少佈局嵌套,儘可能不要在UI線程做過多耗時操作。

(5)OverDraw過度繪製

當設計上追求更華麗的視覺效果的時候,我們就容易陷入採用複雜的多層次重疊視圖來實現這種視覺效果的怪圈。這這很容易導致大量的性能問題,爲了獲得最佳的性能,我們必須儘量減少Overdraw的情況發生。


圖 1-6 過度繪製四種級別示例圖

藍色、淡綠、淡紅、深紅代表了4種不同程度的Overdraw情況,我們的目標就是儘量減少紅色Overdraw,看到更多的藍色區域。

(6)GC垃圾回收

GC一般耗時在幾毫秒到幾百毫秒之間,然而對於手機16ms渲染機制來說,GC會帶來不小的開銷,所以在開發過程中儘量避免顯示調用GC。頻繁GC會導致頁面卡頓,當執行GC操作時,任何線程都進入暫停狀態,等待GC操作結束後才能夠繼續運行。導致頻繁GC有兩個原因:

1、        內存抖動,即大量的對象被創建後又在短時間內立刻被釋放

2、        瞬間產生大量的對象會嚴重佔用Young Generation的內存區域,當達到閥值時會觸發GC過程。

以上這些GC操作可能會造成丟幀情況,如下圖:


圖 1-7 GC時丟幀示例圖

24ms的GC形成了丟幀,用戶感知到頁面卡頓。

(7)同步任務過多

頁面啓動時同步任務過多會在短期內過多佔用手機資源,直接導致其他性能下降,影響頁面響應時間。例如在Activity的onCreate方法中進行了大量的同步任務。

二、 初步優化方案

綜上所述,App運行速度分析概括爲以下七點:硬件約束、網絡環境影響以及服務器接口環境、View的繪製過程、16ms原則、OverDraw過度繪製、GC垃圾回收、同步任務過多。在這裏我們只對移動端開發並對後面五點提出相應的初步優化方案:異步延遲加載。

不妨先針對View的繪製過程、16ms原則來分析下某首頁,採用hierarchyviewer工具分析首頁如下:


圖 2-1 首頁MLD分析示例圖

從上圖可以看出首頁包含了1435個view,Measure耗時43.476ms,Layout耗時1.141ms,Draw耗時2.840,總耗時47.457ms(大於16ms)。基於16ms原則,該頁面會出現丟幀情況從而導致卡頓現象。針對這種長篇幅的頁面可以根據實際情況進行異步延遲加載,對於第三屏、第四屏、第五屏採用梯級延遲加載從而避開同步加載。

異步延遲加載的關鍵是延遲時間爲多少是合適的,對於配置較低的手機延遲相對要高一些,對於配置較高的手機延遲相對要低一些。如果延遲配置的不合理的話,高配置手機會產生等待延遲加載的內容的情況,而低配置手機會出現優化效果不明顯的情況。所以這個時間需要結合業務以及不同配置的手機進行測試來確定的。

針對GC垃圾回收,我們以某APP MainActivity爲例子分析下。MainActivity作爲項目中所有Activity的託管,採用getLocalActivityManager().startActivity().getDecorView()方法獲取啓動Activity的視圖進行顯示。jumpActivity爲切換Activity的方法,每次進行頁面跳轉時必須經過該方法,該方法包含GC過程。通過測試分析統計出每次跳轉頁面GC的耗時在8ms到300毫秒之間,這裏的GC時間會隨着下個啓動頁面的工作量越多而耗時越長。我們採用異步處理一下,GC過程耗時在0~4ms之間,效果提升顯著。

使用低配置的手機打開某APP進入首頁時會黑屏8~·14秒,然後出現界面,通過代碼分析發現首頁同步初始化五個重量級的Fragment,導致系統運存缺乏,影響了後續的界面繪製渲染等邏輯。我們採用異步延遲加載進行處理一下,先對第一個主Fragment進行異步加載,主Fragment加載完畢後再異步加載第二個Fragment,接着第三個,最後第四個,這樣就可以在短時間內合理分配運存,避免了黑屏的情況。

以上就是App運行速度分析以及初步優化方案,我們只有對App運行速度的硬件環境、開發的軟件因素以及App運行交互的原理進行了解後才能制定相應的優化方法,方可對症下藥。對於每一個可能影響用戶體驗的問題進行逐步優化,以先解決大問題、迫切問題爲前提,以解決繁瑣、細小的問題爲原則進行深入優化,App體驗纔會越來越好。

 

參考資料:

Android App優化之消除卡頓

Android應用啓動優化:一種DelayLoad的實現和原理

Android性能優化之渲染篇

Android中View繪製流程以及invalidate()等相關方法分析

Android UI性能優化詳解

關於Android中16ms的問題

破譯Android性能優化中的16ms問題

設計師必須注意的Android開發者選項之GPU過度繪製

Android開發之淺談垃圾回收機制GC以及如何用好GC

 

發佈了44 篇原創文章 · 獲贊 37 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章