1. 簡介
上次更新時間:2021 年 3 月 11 日
為什麼必須評估觀看次數成效?
檢視畫面是 Android 應用程式中直接影響使用者體驗的重要部分。舉例來說,「活動」或「片段」包含的 UI,會保留使用者與其互動的 View 元件。使用者無法查看 UI 的完整內容,直到 UI 內容完全繪製在螢幕上。緩慢和凍結畫面會直接影響使用者與應用程式的互動,並造成不良的使用者體驗。
Firebase Performance Monitoring 不會立即提供這些成效指標嗎?
Firebase 效能監控功能會自動擷取部分立即運作的效能資料,例如應用程式的啟動時間 (僅限「第一個」活動的載入時間) 和畫面轉譯效能 (例如「活動」的緩慢和凍結影格,但「片段」則不適用)。不過,業界應用程式通常沒有大量活動,而是只有一個活動和多個片段。此外,許多應用程式通常會實作自訂檢視區塊,以因應更複雜的用途。因此,瞭解如何在應用程式中檢測自訂程式碼追蹤記錄,以評估活動和片段的載入時間和畫面轉譯效能,總會很有幫助。您可以輕鬆擴充本程式碼研究室,評估自訂檢視區塊元件的效能。
課程內容
- 如何將 Firebase Performance Monitoring 新增至 Android 應用程式
- 瞭解活動或片段的載入方式
- 如何檢測自訂程式碼追蹤記錄以評估活動或片段的載入時間
- 瞭解螢幕轉譯作業和緩慢/凍結影格是什麼
- 如何檢測自訂程式碼追蹤記錄和指標,以記錄緩慢/凍結畫面
- 如何在 Firebase 控制台中查看收集到的指標
軟硬體需求
- Android Studio 4.0 以上版本
- Android 裝置/模擬器
- Java 8 以上版本
2. 開始設定
取得程式碼
執行下列指令,複製本程式碼研究室的程式碼範例。這項操作會在您的電腦上建立名為 codelab-measure-android-view-performance
的資料夾:
$ git clone https://github.com/FirebaseExtended/codelab-measure-android-view-performance.git
$ cd codelab-measure-android-view-performance
如果您的機器中沒有 Git,您也可以直接從 GitHub 下載程式碼。
將 measure-view-performance-start
專案匯入 Android Studio。您可能會看到一些編譯錯誤,或是因為缺少 google-services.json
檔案而收到警告訊息。我們會在這個步驟的下一節修正這個問題。
在本程式碼研究室中,我們會使用 Firebase Assistant 外掛程式,向 Firebase 專案註冊 Android 應用程式,並將必要的 Firebase 設定檔、外掛程式和依附元件加入 Android 專案 — 只需在 Android Studio 中就能完成!
將應用程式連結至 Firebase
- 前往「Android Studio」/「Help」(說明) >請檢查更新,確保您使用的是最新版的 Android Studio 和 Firebase Assistant。
- 選取「工具」>Firebase,開啟「Assistant」窗格。
- 選擇「Performance Monitoring」新增到應用程式,然後按一下「開始使用 Performance Monitoring」。
- 按一下「連結至 Firebase」,將 Android 專案連結至 Firebase (這會在瀏覽器中開啟 Firebase 控制台)。
- 在 Firebase 控制台中按一下「新增專案」,然後輸入 Firebase 專案名稱(如果您已有 Firebase 專案,可以改為選取該現有專案)。按一下「繼續」並接受條款,以建立 Firebase 專案和新的 Firebase 應用程式。
- 接著您應該會看到一個對話方塊,將新的 Firebase 應用程式連結至 Android Studio 專案。
- 返回 Android Studio 的「Assistant」窗格,您應該會看到確認應用程式已連線至 Firebase。
在應用程式中新增 Performance Monitoring
在 Android Studio 的「Assistant」窗格中,按一下「Add Performance Monitoring to app」。
系統應會顯示「Accept Changes」對話方塊,然後 Android Studio 應同步處理應用程式,以確保已新增所有必要的依附元件。
最後,Android Studio 的「Assistant」窗格應會顯示成功訊息,指出所有依附元件皆已正確設定。
另外,請按照「(選用) 啟用偵錯記錄功能」步驟中的操作說明啟用偵錯記錄功能。公開說明文件也提供相同的操作說明。
3. 執行應用程式
如果您已成功將應用程式與 Performance Monitoring SDK 整合,現在應該就能編譯專案。在 Android Studio 中,按一下「Run」(執行) >執行「應用程式」,在已連結的 Android 裝置/模擬器上建構及執行應用程式。
應用程式有兩個按鈕,可將您導向對應的 Activity 和 Fragment,如下所示:
在本程式碼研究室的後續步驟中,您將瞭解如何評估活動或片段的載入時間和畫面轉譯效能。
4. 瞭解活動或片段的載入方式
在這個步驟中,我們會瞭解系統在載入活動或片段時正在執行什麼作業。
瞭解活動載入
對活動而言,載入時間是指從活動物件建立到一直到畫面呈現第一個畫面為止 (也就是使用者首次看到活動的完整 UI 時) 開始的時間。如要評估應用程式是否已完整繪製,可以使用 reportFullyDrawn()
方法測量應用程式啟動之間經過的時間,以及完成所有資源和檢視區塊階層的顯示時間。
大致來說,當應用程式呼叫 startActivity(Intent)
時,系統會自動執行下列程序。每個程序皆需要時間才能完成,因此加上從活動建立到使用者在畫面上看到活動 UI 的間隔時間。
瞭解 Fragment 的載入方式
片段的載入時間與 Fragment 的載入時間類似,定義是從 Fragment 附加至代管活動時起算,直到 Fragment View 的第一個影格為止繪製在畫面上為止。
5. 測量活動的載入時間
第一個影格發生延遲可能會導致使用者體驗不佳,因此請務必瞭解使用者在初始載入時花費多少時間。您可以檢測自訂程式碼追蹤記錄以測量這項載入時間:
- 建立 Activity 物件後,立即在 Activity 類別中啟動自訂程式碼追蹤記錄 (名為
TestActivity-LoadTime
)。
TestActivity.java
public class TestActivity extends AppCompatActivity {
// TODO (1): Start trace recording as soon as the Activity object is created.
private final Trace viewLoadTrace = FirebasePerformance.startTrace("TestActivity-LoadTime");
// ...
}
- 覆寫
onCreate()
回呼,並取得setContentView()
方法加入的 View。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Current Activity's main View (as defined in the layout xml file) is inflated after this
setContentView(R.layout.activity_test);
// ...
// TODO (2): Get the View added by Activity's setContentView() method.
View mainView = findViewById(android.R.id.content);
// ...
}
- 我們已加入
FistDrawListener
實作,其中包含兩個回呼:onDrawingStart()
和onDrawingFinish()
(如要進一步瞭解FirstDrawListener
以及可能影響其效能的因素,請參閱下一節)。在 Activity 的onCreate()
回呼結尾註冊FirstDrawListener
。您應在onDrawingFinish()
回呼中停止viewLoadTrace
。
TestActivity.java
// TODO (3): Register the callback to listen for first frame rendering (see
// "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when View drawing is
// finished.
FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {
@Override
public void onDrawingStart() {
// In practice you can also record this event separately
}
@Override
public void onDrawingFinish() {
// This is when the Activity UI is completely drawn on the screen
viewLoadTrace.stop();
}
});
- 重新執行應用程式。然後使用「Logging 追蹤指標」篩選 logcat。輕觸
LOAD ACTIVITY
按鈕,然後查看類似下方的記錄:
I/FirebasePerformance: Logging trace metric: TestActivity-LoadTime (duration: XXXms)
🎉? 恭喜!您已成功評估活動的載入時間,並將相關資料回報至 Firebase Performance Monitoring。本程式碼研究室稍後會在 Firebase 控制台中查看記錄指標。
FirstDrawListener 的用途
在上面的部分中,我們註冊了 FirstDrawListener
。FirstDrawListener
的用途是測量第一個影格開始和結束繪圖的時間。
這個函式會實作 ViewTreeObserver.OnDrawListener
並覆寫 onDraw()
回呼,以在 View 樹狀結構即將繪製時叫用。接著會包裝結果,提供兩個公用程式回呼 onDrawingStart()
和 onDrawingFinish()
。
您可以在這個程式碼研究室的原始碼中找到 FirstDrawListener
的完整程式碼。
6. 測量片段的載入時間
Fragment 的載入時間的測量方式,與我們為 Activity 測量時類似,但有些微差異。同樣地,我們會檢測自訂程式碼追蹤記錄:
- 覆寫
onAttach()
回呼,並開始記錄fragmentLoadTrace
。我們將這個追蹤記錄命名為Test-Fragment-LoadTime
。
正如先前步驟所說明,Fragment 物件隨時都能建立,但只有在附加至其主機 Activity 時才會啟用。
TestFragment.java
public class TestFragment extends Fragment {
// TODO (1): Declare the Trace variable.
private Trace fragmentLoadTrace;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
// TODO (2): Start trace recording as soon as the Fragment is attached to its host Activity.
fragmentLoadTrace = FirebasePerformance.startTrace("TestFragment-LoadTime");
}
- 在
onViewCreated()
回呼中註冊FirstDrawListener
。接著,與 Activity 範例類似,請停止onDrawingFinish()
中的追蹤記錄。
TestFragment.java
@Override
public void onViewCreated(@NonNull View mainView, Bundle savedInstanceState) {
super.onViewCreated(mainView, savedInstanceState);
// ...
// TODO (3): Register the callback to listen for first frame rendering (see
// "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when view drawing is
// finished.
FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {
@Override
public void onDrawingStart() {
// In practice you can also record this event separately
}
@Override
public void onDrawingFinish() {
// This is when the Fragment UI is completely drawn on the screen
fragmentLoadTrace.stop();
}
});
- 重新執行應用程式。然後使用「Logging 追蹤指標」篩選 logcat。輕觸
LOAD FRAGMENT
按鈕,然後查看類似下方的記錄:
I/FirebasePerformance: Logging trace metric: TestFragment-LoadTime (duration: XXXms)
🎉? 恭喜!您已成功評估片段的載入時間,並將相關資料回報至 Firebase Performance Monitoring。本程式碼研究室稍後會在 Firebase 控制台中查看記錄指標。
7. 瞭解螢幕轉譯作業和緩慢/凍結影格是什麼
UI 轉譯是指從應用程式產生並在螢幕中顯示影格的動作。為了確保使用者與應用程式的互動順暢,應用程式的影格轉譯速度應在 16 毫秒以內,才能達到每秒 60 個影格 ( 為什麼是 60fps?)。如果應用程式的 UI 顯示速度緩慢,系統會強制略過影格,使用者就會感覺到應用程式有延遲現象。我們稱之為「卡頓」。
同樣地,凍結影格是指轉譯時間超過 700 毫秒的 UI 影格。這段延遲會造成問題,因為應用程式在顯示時似乎停滯不動,且在影格轉譯時幾乎有整整一秒沒有回應使用者輸入內容。
8. 評估片段的緩慢/凍結影格
Firebase Performance Monitoring 會自動擷取活動速度緩慢/凍結的影格 (僅限硬體加速)。不過,Fragment 目前無法使用這項功能。Fragment 的緩慢/凍結影格是指在 Fragment 生命週期中,整個活動在 onFragmentAttached()
和 onFragmentDetached()
回呼之間的緩慢/凍結影格。
我們採取 AppStateMonitor
類別 (負責記錄「活動」螢幕追蹤記錄的 Performance Monitoring SDK 的一部分) 做為動機,而導入 ScreenTrace
類別 (這是本程式碼研究室原始碼存放區的一部分)。ScreenTrace
類別可連結至活動的 FragmentManager
生命週期回呼,以擷取緩慢/凍結影格。這個類別提供兩個公用 API:
recordScreenTrace()
:開始錄製螢幕追蹤記錄sendScreenTrace()
:停止錄製螢幕畫面追蹤記錄,並附加自訂指標,記錄總影格數、緩慢影格和凍結影格數
附加這些自訂指標後,Fragment 的螢幕追蹤記錄處理方式和「活動」的畫面追蹤記錄相同,而且可以連同其他畫面轉譯追蹤記錄一起顯示在 Firebase 控制台的「效能」資訊主頁中。
以下說明如何為 Fragment 記錄畫面追蹤記錄:
- 在代管片段的活動中初始化
ScreenTrace
類別。
MainActivity.java
// Declare the Fragment tag
private static final String FRAGMENT_TAG = TestFragment.class.getSimpleName();
// TODO (1): Declare the ScreenTrace variable.
private ScreenTrace screenTrace;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TODO (2): Initialize the ScreenTrace variable.
screenTrace = new ScreenTrace(this, FRAGMENT_TAG);
// ...
}
- 載入 Fragment 時,請註冊
FragmentLifecycleCallbacks
並覆寫onFragmentAttached()
和onFragmentDetached()
回呼。我們已為你處理這個問題。您需要在onFragmentAttached()
回呼中開始錄製螢幕追蹤記錄,並在onFragmentDetached()
回呼中停止記錄。
MainActivity.java
private final FragmentManager.FragmentLifecycleCallbacks fragmentLifecycleCallbacks =
new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {
super.onFragmentAttached(fm, f, context);
// TODO (3): Start recording the screen traces as soon as the Fragment is
// attached to its host Activity.
if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
screenTrace.recordScreenTrace();
}
}
@Override
public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {
super.onFragmentDetached(fm, f);
// TODO (4): Stop recording the screen traces as soon as the Fragment is
// detached from its host Activity.
if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
screenTrace.sendScreenTrace();
}
// Unregister Fragment lifecycle callbacks after the Fragment is detached
fm.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks);
}
};
- 重新執行應用程式。然後輕觸「
LOAD FRAGMENT
」按鈕。等待幾秒鐘,然後按一下底部導覽列的back button
。
使用「記錄追蹤記錄指標」篩選 logcat,然後尋找類似下方的記錄:
I/FirebasePerformance: Logging trace metric: _st_MainActivity-TestFragment (duration: XXXms)
使用「FireperfViews」篩選 logcat,再查看下列記錄:
D/FireperfViews: sendScreenTrace MainActivity-TestFragment, name: _st_MainActivity-TestFragment, total_frames: XX, slow_frames: XX, frozen_frames: XX
🎉? 恭喜!您已成功評估片段的緩慢/凍結影格,並將相關資料回報至 Firebase Performance Monitoring。稍後在這個程式碼研究室中,我們會到 Firebase 控制台查看記錄的指標。
9. 在 Firebase 控制台中查看指標
- 在 logcat 中,按一下 Firebase 主控台網址,前往追蹤記錄的詳細資料頁面。
您也可以在 Firebase 控制台,選取含有您應用程式的專案。在左側面板中,找到「發布與」監控部分,然後按一下「效能」。
- 在主要「資訊主頁」分頁中,向下捲動至追蹤記錄表格,然後按一下「自訂追蹤記錄」分頁標籤。在這個表格中,您會看到我們稍早新增的自訂程式碼追蹤記錄,以及一些立即可用的追蹤記錄,例如
_app_start
追蹤記錄。 - 找出
TestActivity-LoadTime
和TestFragment-LoadTime
這兩個自訂程式碼追蹤記錄。按一下任一項的「時間長度」,即可查看收集資料的更多詳情。
- 自訂程式碼追蹤記錄的詳細資料頁面會顯示追蹤記錄時間長度 (也就是測量的載入時間) 的資訊。
- 您也可以查看自訂畫面追蹤記錄的效能資料。
- 返回「資訊主頁」主分頁,向下捲動至追蹤記錄表格,然後按一下「畫面轉譯」分頁標籤。在這個表格中,您會看到我們稍早新增的自訂畫面追蹤記錄,以及任何立即可用的螢幕追蹤記錄 (例如
MainActivity
追蹤記錄)。 - 找出自訂畫面追蹤記錄
MainActivity-TestFragment
,按一下追蹤記錄名稱,即可查看轉譯速度緩慢和凍結影格的匯總資料。
10. 恭喜
恭喜!您已成功使用 Firebase Performance Monitoring,評估活動和片段的載入時間和畫面轉譯效能!
您的成就
- 您已將 Firebase Performance Monitoring 整合至範例應用程式
- 您已瞭解載入檢視畫面的生命週期
- 您已新增自訂程式碼追蹤記錄,藉此測量活動和片段的載入時間
- 您新增含有自訂指標的自訂畫面追蹤記錄,藉此記錄緩慢/凍結影格
後續步驟
除了自訂追蹤記錄以外,Firebase 效能還提供更多評估應用程式效能的方式。系統會自動測量應用程式啟動時間、前景應用程式,以及應用程式在背景運作的效能資料。屆時您可以在 Firebase 控制台查看這些指標。
此外,Firebase Performance 也提供自動 HTTP/S 網路要求監控功能。透過這個工具,您無須編寫任何程式碼即可輕鬆檢測網路要求。請先嘗試透過應用程式傳送網路要求,並在 Firebase 控制台中尋找指標嗎?
獎勵
現在您已經瞭解如何利用自訂程式碼追蹤記錄,評估活動/片段的載入時間和畫面轉譯效能,不妨看看我們的開放原始碼程式碼集,看看能否從應用程式的任何活動/片段中直接擷取這些指標?如有需要,歡迎直接傳送 :-)
11. 額外學習
瞭解載入活動期間會發生的情況,可協助您進一步瞭解應用程式的效能特性。在前一步驟中,我們大致說明瞭載入活動期間會發生的情況,但下圖更詳細地說明每個階段。