評估應用程式效能總覽

Stay organized with collections Save and categorize content based on your preferences.

此主題可協助您找出並修正應用程式的主要效能問題。

主要效能問題

許多問題都會導致應用程式效能低落,以下列舉幾種應用程式應注意的常見情況:

  • 捲動資源浪費
    • 「資源浪費」(Jank) 這個術語,是用來描述系統無法依要求的頻率 (例如 60 Hz 或更高) 及時建構和提供影格,導致畫面出現斷斷續續的情況。資源浪費在捲動時最容易出現,比如說因為應用程式轉譯內容所需的時間比系統畫面的持續時間還長,所以畫面移動時會在一個或多個畫面中暫停,導致原本應該流暢的動畫流程變得斷斷續續。
    • 應用程式的刷新率應設定為 90 Hz。傳統的轉譯率為 60 Hz,但許多新型的裝置在使用者互動 (例如捲動) 時都是在 90 Hz 的模式下運作,而且有些裝置甚至支援更高的頻率 (最高 120 Hz)。
      • 如要查看裝置在特定時間的刷新率,請依序輕觸「開發人員選項」>「偵錯」部分的「顯示刷新率」,即可啟用在畫面上疊加顯示刷新率的功能。
  • 啟動延遲

    • 啟動延遲時間是從輕觸應用程式圖示、通知或其他進入點開始,直到使用者資料顯示在畫面上所需的時間。
    • 您的目標是在應用程式中建立下列兩個啟動目標:

      • 冷啟動 < 500 毫秒:如果系統記憶體中沒有啟動應用程式的記錄,就會出現「冷啟動」。這是應用程式自重新啟動,或使用者或系統終止應用程式的程序後首次啟動時會出現的情形。

        相反的,如果應用程式已在背景執行,就會發生「暖啟動」。冷啟動需要系統處理大部分作業,因為系統必須從儲存空間載入各種項目並初始化應用程式。您的目標是讓冷啟動的目標不超過 500 毫秒。

      • 讓 P95/P99 延遲時間非常接近中位數延遲時間。 如果應用程式有的時候需要很長的時間才能啟動,使用者就會對應用程式逐漸失去信任。在應用程式啟動的重要路徑中,IPC 和不必要的 I/O 可能會遭遇鎖定爭用的情況,並造成這些不一致的問題。

  • 轉換不順暢

    • 這些問題會在互動期間發生,例如:切換分頁或載入新活動。這些類型的轉換應有流暢的動畫,且不應出現延遲或視覺效果閃爍的情況。
  • 電源效率不佳

    • 執行作業會消耗電池電力,而執行不必要的作業會降低電池續航力。
    • 記憶體配置 (在程式碼中建立新物件) 可能會導致系統作業負載增加。這是因為配置作業不僅須透過 Android 執行階段完成,稍後釋出這些物件 (「垃圾收集」) 也需要時間與操作。現在的配置和收集速度都比以前更快,效率也更高,對於暫存物件而言更是如此。因此,過去的準則都是建議盡可能避免配置物件,現在則是盡量以最合理的方式執行應用程式和架構;由於 ART 有強大的功能,因此冒險使用無法維護的程式碼以減少配置並非合適的選擇。

      即便如此,系統仍然必須執行操作,因此建議您以是否在內部迴圈中配置多個物件做為考量,因為這也可能會導致發生效能不佳的情況。

辨別問題

辨別效能問題並進行補救的建議工作流程如下:

  • 辨別關鍵使用者旅程並進行檢查。其中可能包括:
    • 常見的啟動流程,包括啟動器和通知。
    • 使用者捲動資料的任何畫面。
    • 畫面之間的轉換。
    • 長時間執行的流程,例如導航或播放音樂。
  • 在這些流程期間使用偵錯工具進行檢查:
    • Systrace 或 Perfetto:可讓您利用精確的時間資料瞭解裝置中運作的確切情況。
    • 記憶體分析器:可讓您查看堆積上的記憶體配置情形。
    • Simpleperf:以火焰圖方式檢視在特定時間之內佔用大多數 CPU 的函式呼叫。如果發現某些項目在 Systrace 中花費的時間較長,但又不知道原因為何,Simpleperf 就可以提供其他資訊。

對於瞭解這些效能問題並進行除錯而言,個別測試的手動除錯非常重要。以上步驟無法以分析匯總資料取代。不過,在自動化測試和實際環境中設定指標收集也很重要,因為這可協助您瞭解使用者實際可看到的畫面,並找出可能發生迴歸的時間點:

  • 啟動流程
  • 資源浪費
    • 實際環境指標
      • Play 管理中心影格指標:請注意,您無法在 Play 管理中心將指標範圍縮小至特定使用者歷程,因為回報的所有內容是應用程式整體資源浪費的情形。
      • 使用 FrameMetricsAggregator 自訂評估:您可以在特定工作流程中使用 FrameMetricsAggregator 記錄資源浪費指標。
    • 研究室測試
      • Jetpack Macrobenchmark:捲動
      • Macrobenchmark 會使用包含單一使用者歷程的 dumpsys gfxinfo 指令收集影格時間。要瞭解特定使用者歷程中資源浪費的不同情況,這是可以合理使用的方式。RenderTime 指標會醒目顯示影格的繪製時間,這對辨識迴歸或改善而言,比資源浪費影格的計數要更為重要。

設定應用程式進行效能分析

正確設定是應用程式取得準確、可重複且可操作的效能評定關鍵。進行測試時,請盡可能使用最接近實際工作環境的系統,同時抑制雜訊來源。下列各節說明準備測試設定時可以採用的 APK 與特定系統步驟,其中有些步驟僅適用於特定用途。

追蹤點

應用程式可以透過自訂追蹤記錄事件檢測程式碼。

擷取追蹤記錄時,追蹤記錄在每個區段中都會產生少許額外負荷 (約 5 μs),因此請避免在每種方法中都加入追蹤記錄。追蹤記錄大型工作區塊 (>0.1 毫秒),就足以提供重要的瓶頸深入分析。

APK 注意事項

注意:請勿評估偵錯版本的效能。

偵錯變化版本可協助您進行疑難排解,還可以透過符號方式提供堆疊樣本,但這會對效能造成嚴重的非線性影響。在執行 Android 10 (API 級別 29) 以上版本的裝置中,您可以使用資訊清單中的 profileable android:shell="true" 以啟用發布子版本的剖析。

使用實際執行等級的程式碼縮減設定。視應用程式使用的資源而定,這可能會對效能產生重大影響。請注意,部分 ProGuard 設定會移除追蹤記錄點,因此建議您針對要執行測試的設定移除這些規則。

編譯

將裝置端應用程式編譯為已知狀態 (通常是速度或速度概況)。 背景 JIT 活動可能會產生龐大的效能負荷,因此在測試執行期間重新安裝 APK 時,經常會發生這種情況。執行此操作的指令如下:

adb shell cmd package compile -m speed -f com.google.packagename

「速度」編譯模式會完整編譯應用程式;「速度概況」模式會根據使用應用程式期間所收集的程式碼路徑概況編譯應用程式。持續以正確方式收集概況可能並不容易,因此如果決定使用,請確認這些資料都是以您預期的方式進行收集。概況位置:

/data/misc/profiles/ref/[package-name]/primary.prof

請注意,Macrobenchmark 可讓您直接指定編譯模式

系統注意事項

如要進行低層級和高精確度的測量,請校正裝置。在相同的裝置和相同的 OS 版本中執行 A/B 版本比較。即使使用同樣的裝置類型,效能也可能會有顯著變化。

在已解鎖裝置中,請考慮使用 lockClocks 指令碼執行微型效能評定。此外,指令碼也可以執行以下操作:

  • 將 CPU 設為固定頻率。
  • 停用小型核心設定 GPU。
  • 停用熱節流。

不建議針對使用者體驗進行集中測試 (例如應用程式啟動、DoU 測試和資源浪費測試),但這對於微型效能評定測試中的減少雜訊卻是不可或缺的一環。

建議盡可能使用測試架構,例如 Macrobenchmark,以減少評估中的雜訊,避免評估不準確。

應用程式啟動速度緩慢:非必要的 Trampoline 活動

Trampoline 活動可能會不必要地延長應用程式啟動時間,因此請務必瞭解應用程式是否正常運作。在以下追蹤記錄範例中,一個 activityStart 後面緊接著是 activityStart,且第一個活動沒有繪製任何影格。

alt_text

這種情況在通知進入點和一般應用程式啟動進入點都可能發生,而且通常可以透過重構來解決。舉例來說,如果在執行另一個活動之前使用該活動執行設定,請執行因式分解為可重複使用的元件或程式庫。

非必要配置觸發常用 GC

您可能會發現垃圾收集 (GC) 的頻率比 Systrace 中預期的發生頻率高。

在這種情況下,在長時間執行的作業期間,每 10 秒是一個指標,代表應用程式可能遭到不必要的分配,但有時仍會持續運作:

alt_text

或者,您可能會發現在使用記憶體分析器時,呼叫堆疊會佔大部分的分配比例。您不需要主動刪除所有配置,因為這樣可能會導致程式碼更加難以維護。建議改從使用分配熱點開始。

資源浪費影格

圖形管線的複雜度相對較高,為了判斷使用者最後是否看見捨棄的影格,可能會有些許細微的影響。在某些情況下,平台可以使用緩衝功能來「找回」影格。不過您可以忽略大部分的細微差異,直接從應用程式的角度輕鬆找出有問題的影格。

如果繪製的影格幾乎都在應用程式中完成,Choreographer.doFrame() 追蹤記錄點就會以 16.7 毫秒的步調 (假設是 60 FPS 裝置) 出現:

alt_text

縮小並瀏覽追蹤記錄時,有時會發現影格完成處理的所需時間比較長,但因為影格處理的所需時間沒有超過 16.7 毫秒,所以不會造成太大影響:

alt_text

如果實際看到一般步調遭中斷,就代表有資源浪費影格:

alt_text

只要練習幾次,就可以輕鬆讀懂。

alt_text

在某些情況下,您必須放大檢視該追蹤記錄點,以進一步瞭解哪些檢視畫面正在加載,或 RecyclerView 正在執行哪些操作。如果是其他情況下,您可能需要進一步檢查。

如要進一步瞭解識別資源浪費影格並偵錯以找出原因,請參閱「轉譯速度緩慢」。

RecyclerView 常見錯誤

  • 以不必要的方式使整個 RecyclerView 的備份資料失效。這可能會導致畫面轉譯時間過長,並造成資源浪費。請改為僅使已經變更的資料失效,從而減少必須更新的檢視畫面數目。
    • 請參閱「呈現動態資料」,瞭解如何避免成本高昂的 notifyDatasetChanged() 呼叫 (導致內容更新而非全面取代)。
  • 無法正確支援巢狀 RecyclerView,導致內部 RecyclerView 每次都要全部重建。
    • 每個巢狀的內部 RecyclerView,都應有 RecycledViewPool 設定,以確保檢視畫面可在內部 RecyclerView 之間回收。
  • 資料量預先擷取不足,或是未及時預先擷取。快速到達捲動清單的底部後,必須等候伺服器傳來更多資料,這可能會讓人感到不耐煩。雖然技術上來說這不算「資源浪費」 (因為操作仍然符合影格顯示期限),但要修改預先擷取的時間和數量,讓使用者不需要等候資料顯示,也可能是重要的 UX 改善工程。