目前為止,我們已經介紹了幾種影響效能的因素及解決方式:
App 啟動時間過長 → 延後初始化或使用 Startup library
App 檔案過大 → 精簡 App 的檔案大小
ANR 應用程式沒有回應 → 將耗時工作移到背景
其中對效能最有影響的就是在主執行緒執行了耗時的工作而造成 UI 延遲。儘管我們已經不在主執行緒執行耗時的工作,仍有其他因素會造成 UI 的延遲。例如在 60fps 的情況,每 16 毫秒渲染一次 UI,而這裡做的渲染太過複雜,導至 UI 有所延遲。會讓渲染複雜的原因有:
接下來我們就要進入到 Layout 的效能優化篇,依序將介紹:
在開始進行 Layout 的優化前,這一篇就先來介紹造成 UI 的延遲的一些相關知識。
Refresh rate 指的是螢幕 1 秒圖像變換的頻率,其單位是 Hz。早期 Android 裝置的 Refresh reate 是 60Hz,現在大部分的裝置在與使用者互動時都有到 90Hz,甚至更高的到 120Hz。
你可以在你的手機開啟顯示Refresh rate 來看看。在手機點選「開發人員選項」 → 「顯示重新整理率」,可以看到畫面上就會顯示 Refresh rate的數字。以我的手機 Pixel 6 為例,靜止的時候是 60Hz,有互動的時候則是 90Hz。
Frame rate 則是指 GPU 一秒內繪制的幀數 (frame) ,單位是 fps (frame per second)。如果 Frame rate 是 60 fps,也就是每秒可以繪製 60 個 frame。我們用 1(秒) / 60( frames ) 就可以得知每 16 毫秒要更新一個 frame。Frame rate 越高,代表每一秒內顯示畫面動作的影像越多,我們看到的畫面就越流暢,以現在的手機,最好可以支援到 1 秒 90 個 frame。
在每 16 毫秒就渲染一張圖的情況下,由於人眼有視覺暫留,所以你看起來就會像是連續的動態影像。如下圖 Android 圖示會以順時針的方式旋轉。
如果是 90fps,也就是每 11 毫秒更新一次。Frame rate 提高到 90,每一秒內顯示的畫面動作影像就越多、越細緻,看起來就更流暢。
要可以流暢的感受到 60 fps,就要每 16 毫秒對 UI 的渲染都要成功。當我們在UI執行緒執行耗時的工作,在UI 執行緒上就無法即時的進行順利的渲染,系統就會強制略過 (dropped) 這個frame,使用者就會感受到延遲。而這個被略過的 frame,我們就叫他 Janky frame。
如下圖,在如果在這每 16 毫秒更新一次 frame 的過程,在處理耗時工作或 Layout 無法順利渲染,就會發生Jank。使用者就會覺得下圖 Android Icon 旋轉的過程就會覺得中間有卡住。
反過來說,如果主執行緒執行的工作能在 16 毫秒內完成,就不會造成 UI 的延遲。所以倒也不是完全不能在 UI 執行緒上執行一些計算,只有真的耗時的例如網路請求、檔案存取等等是你應該避免的。
到這裡我們對 UI 為什麼卡住,已經有一些基本的了解。下一篇就再接著介紹 View 是怎麼繪製的。
參考:
https://developer.android.com/guide/topics/media/frame-rate