《移動App性能評測與優化》筆記--APP性能測試之FPS\流暢度

1、FPS

騰訊GT爲了更準備的來評測App的流暢度,尋找了一種新的評測方法來替代FPS,把這種新的方法命名爲流暢度(SM)

用FPS測試APP時遇到的問題:

1)爲什麼有時候FPS很低,但是我們卻不覺得App卡頓?

2)App停止操作之後,FPS還是一直在變化,這樣的情況是否會影響FPS的準確度?

系統獲取FPS的原理是這樣的:手機屏幕顯示的內容是通過Android系統的SurfaceFLinger類,把當前系統裏所有進程需要顯示的信息合成一幀,然後提交到屏幕進行顯示。FPS就是1s內SurfaceFLinger提交到屏幕的幀數

根據原理,就可以解答上面的兩個問題:

1)有時候FPS很低,我們卻感覺不到卡頓,是因爲如果你的App在1s內只有30幀的顯示需求,比如畫一個動畫只畫了0.5秒就畫完了,那麼FPS最高也只有30幀/秒,但這並不代表它是卡頓的。而如果屏幕根本沒有繪製需求,即屏幕顯示的畫面是靜止的,那FPS就爲0。

2)App停止操作後FPS還一直變化,是因爲屏幕每一幀的合成都是針對手機裏的所有進程,那麼即使你的App停止了繪製,手機裏其他進程可能還在繪製,比如通知欄的各種消息,這會導致FPS繼續變化。從這裏我們也能看出,在測試的時候,其他的進程對FPS也是有影響的

通過分析發現,用FPS來衡量APP的流暢度,並不一定準確,通過研究FPS的獲取原理,我們對Android的繪製顯示系統有了初步的瞭解,然後我們再對Android的繪製顯示系統進行進一步的分析,終於找到了一種全新的衡量流暢度的方式,就是我們上面說的SM。

(此處需要深入的瞭解Android繪製機制和原理)

流暢度優化過程:

1、通過SM對APP的流暢度進行測試評估

2、然後從最簡單的App UI層入手,優化App的UI來提升流暢度。

  • GPU過度繪製+Trace for OpenGL,解決UI過度繪製的問題(過度繪製是指在屏幕一個像素上繪製多次,可以通過Tracer for OpenGL ES進行詳細的觀察)
  • Hierarchy Viewer,查找UI佈局不合理的地方,主要進行以下幾種分析:                                                                                          1、沒有用的父佈局。沒有用的父佈局是指沒有背景繪製或者沒有大小限制的父佈局,我們把沒有用的父佈局通過<merge/         >標籤合併來減少UI的層次。       

           2、使用線性佈局LinearLayout排版導致UI層次變深。如果有這類問題,我們就使用相對佈局RelativeLayout代替                               LinearLayout,減少UI的層次 

           3、不常用的UI被設置成了GONE,比如error頁面,如果有這類問題,我們需要用<ViewStub />標籤代替GONE提高UI性能

3、接着通過lint靜態掃描發現一部分代碼中存在的性能(Performance)問題,然後進行優化。

4、最後再進一步深入的分析和解決App邏輯層和IO層存在的問題--使用工具Traceview以及Systrace。

  • 找出在主線程耗時較大的函數,看看是否能夠通過優化邏輯去減少API的耗時,優化的方案大概是緩存某些數據在需要的時候能夠更快地加載,或者把耗時的操作移出主線程,或者把滑動的過程中出現的耗時操作延時到滑動停止後纔開始
  • 分析滑動的過程中CPU的工作,看看是否能讓CPU優先執行主線程的工作,儘量不要被其他線程搶佔。

4.1  Traceview,尋找卡住主線程的地方

Traceview可以通過圖形界面的方式讓我們瞭解要跟蹤程序的性能,並且能具體好每個函數的耗時和調用次數,所以我們主要是關注各個函數對性能的影響。一般來說,主要有兩種類型的函數可能會影響到流暢度:

1)主線程裏佔用CPU時間(Incl Cpu Time)很長的函數,特別要留意在主線程的IO操作(文件IO、網絡IO、數據庫操作等)。

首先按CPU佔用時間(Incl Cpu Time)降序排序,然後一個個去觀察,找出哪些耗時的API在主線程上執行,再去看看代碼,是否能移到非主線程執行,如果涉及IO操作看看能否做緩存。

2)主線程調用次數(包括被調用和遞歸調用)很多的函數。

4.2   Systrace,獲取App運行時線程的信息以及API的執行情況

通過在函數前後插入Trace.beginSection(“MainActivity.OnCreate”)和Trace.endSection(),就能看到該函數的耗時和函數的調用關係

Systrace的優點:

1)能直觀地看到每個線程上面API的調用情況,包括API的耗時以及API的調用順序。2)能直觀地看到每個線程的執行情況,包括各個線程的狀態以及耗時,並且能夠統計CPU裏每個線程執行的耗時。3)能夠通過插入代碼的方式,在Systrace裏顯示想要查看的API的耗時以及調用關係。

4.3優化APP的IO層

IO分爲網絡IO和磁盤讀寫IO。在主線程進行長時間或者頻繁的IO操作,對流暢度會有非常大的影響。

  4.3.1 我們通過代碼注入(hook)的方式,hook文件打開關閉以及讀寫的API,採集磁盤IO的信息,IO信息包括讀寫的次數、讀寫的線程、讀寫數據的大小等。然後通過監控的結果來判斷是否存在IO層的問題。

  4.3.2  Android提供的StrictMode

 

 

總結:

1、佈局

     1.1 儘量多使用RelativeLayout和LinearLayout,不要使用絕對佈局Absolute-Layout:a)在佈局層次一樣的情況下,建議使用          LinearLayout代替RelativeLayout,因爲LinearLayout性能要稍高一點。b)在完成相對較複雜的佈局時,建議使用                            RelativeLayout,RelativeLayout可以簡單實現LinearLayout嵌套才能實現的佈局。

   1.2將可複用的組件抽取出來並通過include標籤使用。

    1.3 使用ViewStub標籤來加載一些不常用的佈局。

    1.4 動態地inflation view性能要比SetVisiblity性能要好。當然用VIewStub是最好的選擇。

    1.5  使用merge標籤減少佈局的嵌套層次。

    1.6 去掉多餘的背景顏色,減少過度繪製:a)對於有多層背景顏色的Layout來說,留最上面一層的顏色即可,其他底層的顏色都可以去掉。b)對 於 使 用Selector當 背 景 的Layout(比 如ListView的Item,會 使 用Selector來標記點擊,選擇等不同的狀態),可以將normal狀態的color設置爲“@android:color/transparent”,來解決對應的問題。

    1.7 使用compound drawables:包含ImageView和TextView的LinearLayout可以使用compound drawable實現,這樣更高效               (注:compound drawables是指包含圖片的Textview)

    1.8  內嵌使用包含layout_weight屬性的LinearLayout會在繪製時花費昂貴的系統資源,因爲每一個子組件都需要被測量兩次。           在使用ListView與GridView的時候這個問題顯得尤其重要,因爲子組件會重複被創建,所以要儘量避免使用Layout_weight。

2、針對ListView的性能優化

2.1 複用convertView:在getItemView中,判斷convertView是否爲空,如果不爲空,可複用。

2.2 異步加載圖片,item中如果包含有image,那麼最好異步加載

2.3     快速滑動時不顯示圖片:當快速滑動列表時(SCROLL_STATE_FLING), item中的圖片或獲取需要消耗資源的view,可以不顯示出來;而處於其他兩種狀態(SCROLL_STATE_IDLE和SCROLL_STATE_TOUCH_SCROLL),則將那些view顯示出來。

2.4 item儘可能地減少使用的控件和佈局的層次。同時要儘可能地複用控件,這樣可以減少ListView的內存使用,減少滑動時gc次數。ListView的背景色與cacheColorHint設置相同顏色,可以提高滑動時的渲染性能。

2.5 getView優化:ListView中getView是性能是關鍵,這裏要儘可能地優化。getView方法中不能做複雜的邏輯計算,特別是數據庫和網絡訪問操作,否則會嚴重影響滑動時的性能。

3、解放UI主線程

3.1 不要阻塞UI線程:佔用CPU較多的數據操作儘可能放在一個單獨的線程中進行,通過handler等方式把執行的結果交於UI線程顯        示。特別是針對的網絡訪問、數據庫查詢和複雜的算法。目前Android提供了AsyncTask,Hanlder、Message和Thread的組合。    對於多線程的處理,如果併發的線程很多,同時有頻繁的創建和釋放,可以通過concurrent類的線程池解決線程創建的效率瓶頸。

3.2 不要在UI線程之外操作UI。

 

ps: 還是要去更深入的瞭解一下Android的相關知識,好多名詞都不知道什麼意思   ==

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