1. Einführung
Letzte Aktualisierung: 11. März 2021
Warum müssen wir die Leistung von Aufrufen messen?
Ansichten sind ein wichtiger Bestandteil von Android-Anwendungen, der sich direkt auf die Nutzerfreundlichkeit auswirkt. Ihre Aktivität oder Ihr Fragment enthält beispielsweise die UI, die die View-Komponenten enthält, mit denen Nutzer interagieren. Nutzer können den gesamten Inhalt der Benutzeroberfläche erst sehen, wenn er vollständig auf dem Bildschirm dargestellt wird. Langsame und eingefrorene Bildschirme beeinträchtigen die Nutzerinteraktion mit Ihrer App direkt und führen zu einer schlechten Nutzererfahrung.
Werden diese Leistungsmesswerte nicht standardmäßig von Firebase Performance Monitoring bereitgestellt?
Firebase Performance Monitoring erfasst automatisch einige Leistungsdaten, z.B. die Startzeit Ihrer App (d.h. die Ladezeit nur für Ihre erste Aktivität) und die Bildschirm-Rendering-Leistung (langsame und eingefrorene Frames für Aktivitäten, aber nicht für Fragmente). Branchen-Apps haben jedoch in der Regel nicht viele Aktivitäten, sondern eine Aktivität und mehrere Fragmente. Außerdem implementieren viele Apps in der Regel eigene benutzerdefinierte Ansichten für komplexere Anwendungsfälle. Daher ist es oft hilfreich zu wissen, wie Sie die Ladezeit und die Bildschirmdarstellungsleistung sowohl von Aktivitäten als auch von Fragmenten messen können, indem Sie benutzerdefinierte Code-Traces in Ihrer App instrumentieren. Sie können dieses Codelab ganz einfach erweitern, um die Leistung von Komponenten für benutzerdefinierte Ansichten zu messen.
Aufgaben in diesem Lab
- So fügen Sie einer Android-App Firebase Performance Monitoring hinzu
- Informationen zum Laden einer Aktivität oder eines Fragments
- Anleitung zum Instrumentieren benutzerdefinierter Code-Traces, um die Ladezeit einer Aktivität oder eines Fragments zu messen
- Bildschirmrendering und langsame/eingefrorene Frames
- Benutzerdefinierte Code-Traces mit Messwerten instrumentieren, um langsame/eingefrorene Bildschirme aufzuzeichnen
- Erfasste Messwerte in der Firebase Console aufrufen
Voraussetzungen
- Android Studio 4.0 oder höher
- Ein Android-Gerät/-Emulator
- Java-Version 8 oder höher
2. Einrichtung
Code abrufen
Führen Sie die folgenden Befehle aus, um den Beispielcode für dieses Codelab zu klonen. Dadurch wird auf Ihrem Computer ein Ordner mit dem Namen codelab-measure-android-view-performance
erstellt:
$ git clone https://github.com/FirebaseExtended/codelab-measure-android-view-performance.git
$ cd codelab-measure-android-view-performance
Wenn auf Ihrem Computer kein Git vorhanden ist, können Sie den Code auch direkt von GitHub herunterladen.
Importieren Sie das Projekt measure-view-performance-start
in Android Studio. Wahrscheinlich werden einige Kompilierungsfehler oder eine Warnung zu einer fehlenden google-services.json
-Datei angezeigt. Das korrigieren wir im nächsten Abschnitt dieses Schritts.
In diesem Codelab verwenden wir das Plug-in Firebase Assistant, um unsere Android-App bei einem Firebase-Projekt zu registrieren und die erforderlichen Firebase-Konfigurationsdateien, Plug-ins und Abhängigkeiten zu unserem Android-Projekt hinzuzufügen – direkt in Android Studio.
App mit Firebase verbinden
- Prüfen Sie unter Android Studio/Hilfe > Nach Updates suchen, ob Sie die neuesten Versionen von Android Studio und Firebase Assistant verwenden.
- Wählen Sie Tools > Firebase aus, um den Bereich Assistant zu öffnen.
- Wählen Sie Leistungsüberwachung aus, um sie Ihrer App hinzuzufügen, und klicken Sie dann auf Einführung in die Leistungsüberwachung.
- Klicken Sie auf Connect to Firebase (Mit Firebase verbinden), um Ihr Android-Projekt mit Firebase zu verbinden. Die Firebase Console wird in Ihrem Browser geöffnet.
- Klicken Sie in der Firebase Console auf Projekt hinzufügen und geben Sie einen Firebase-Projektnamen ein. Wenn Sie bereits ein Firebase-Projekt haben, können Sie stattdessen dieses vorhandene Projekt auswählen. Klicken Sie auf Weiter und akzeptieren Sie die Nutzungsbedingungen, um das Firebase-Projekt und eine neue Firebase-App zu erstellen.
- Als Nächstes sollte ein Dialogfeld angezeigt werden, in dem Sie Ihre neue Firebase App mit Ihrem Android Studio-Projekt verknüpfen können.
- In Android Studio sollten Sie im Bereich Assistant die Bestätigung sehen, dass Ihre App mit Firebase verbunden ist.
App Performance Monitoring hinzufügen
Klicken Sie in Android Studio im Bereich Assistant auf App die Leistungsüberwachung hinzufügen.
Es sollte ein Dialogfeld mit der Aufforderung Änderungen akzeptieren angezeigt werden. Anschließend sollte Android Studio Ihre App synchronisieren, um sicherzustellen, dass alle erforderlichen Abhängigkeiten hinzugefügt wurden.
Schließlich sollte im Bereich Assistant in Android Studio die Erfolgsmeldung angezeigt werden, dass alle Abhängigkeiten korrekt eingerichtet sind.
Aktivieren Sie als zusätzlichen Schritt das Debug-Logging. Folgen Sie dazu der Anleitung unter „Optional: Debug-Logging aktivieren“. Die gleiche Anleitung finden Sie auch in der öffentlichen Dokumentation.
3. Anwendung ausführen
Wenn Sie Ihre App erfolgreich in das Performance Monitoring SDK eingebunden haben, sollte das Projekt jetzt kompiliert werden. Klicken Sie in Android Studio auf Ausführen > „App“ ausführen, um die App auf Ihrem verbundenen Android-Gerät/Emulator zu erstellen und auszuführen.
Die App verfügt über zwei Schaltflächen, über die Sie zu einer entsprechenden Aktivität und einem Fragment gelangen:
In den folgenden Schritten dieses Codelabs erfahren Sie, wie Sie die Ladezeit und die Bildschirmdarstellungsleistung Ihrer Aktivität oder Ihres Fragments messen.
4. Informationen zum Laden einer Aktivität oder eines Fragments
In diesem Schritt erfahren wir, was das System beim Laden einer Aktivität oder eines Fragments tut.
Laden einer Aktivität
Bei einer Aktivität ist die Ladezeit als der Zeitraum ab der Erstellung des Activity-Objekts bis zur vollständigen Darstellung des ersten Frame auf dem Bildschirm definiert. Hierdurch sehen die Nutzer zum ersten Mal die vollständige Benutzeroberfläche für die Aktivität. Mit der Methode reportFullyDrawn()
können Sie messen, ob Ihre App vollständig dargestellt wird. Dazu wird die verstrichene Zeit zwischen dem Start der App und der vollständigen Anzeige aller Ressourcen und Ansichtshierarchien gemessen.
Wenn Ihre App startActivity(Intent)
aufruft, führt das System grob gesagt die folgenden Prozesse automatisch aus. Jeder Prozess nimmt einige Zeit in Anspruch, was die Zeitspanne zwischen der Erstellung der Aktivität und dem Zeitpunkt, zu dem der Benutzer die Benutzeroberfläche für die Aktivität auf seinem Bildschirm sieht, verlängert.
Das Laden eines Fragments verstehen
Ähnlich wie bei der Aktivität wird die Ladezeit für ein Fragment als die Zeit definiert, die vergeht, bis das Fragment an seine Host-Aktivität angehängt ist und der erste Frame für die Fragmentansicht vollständig auf dem Bildschirm gezeichnet ist.
5. Ladezeit einer Aktivität messen
Verzögerungen beim ersten Frame können zu einer schlechten Nutzererfahrung führen. Daher ist es wichtig, zu wissen, wie lange die anfängliche Ladezeit für Ihre Nutzer ist. Sie können einen benutzerdefinierten Code-Trace instrumentieren, um diese Ladezeit zu messen:
- Starten Sie den benutzerdefinierten Code-Trace (benannt
TestActivity-LoadTime
) in der Aktivitätsklasse, sobald das Aktivitätsobjekt erstellt wurde.
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");
// ...
}
- Überschreiben Sie den
onCreate()
-Callback und rufen Sie die Ansicht ab, die mit dersetContentView()
-Methode hinzugefügt wurde.
@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);
// ...
}
- Wir haben eine Implementierung von
FistDrawListener
mit zwei Callbacks implementiert:onDrawingStart()
undonDrawingFinish()
(weitere Informationen zuFirstDrawListener
und zu Faktoren, die die Leistung beeinflussen können, findest du im nächsten Abschnitt). Registrieren Sie dieFirstDrawListener
am Ende desonCreate()
-Callbacks der Aktivität. Du solltestviewLoadTrace
imonDrawingFinish()
-Callback beenden.
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();
}
});
- Führen Sie die App noch einmal aus. Filtern Sie dann den Logcat nach Logging trace metric. Tippen Sie auf die Schaltfläche
LOAD ACTIVITY
und suchen Sie nach Logs wie diesen:
I/FirebasePerformance: Logging trace metric: TestActivity-LoadTime (duration: XXXms)
🎉 Glückwunsch! Sie haben die Ladezeit einer Aktivität gemessen und die entsprechenden Daten an Firebase Performance Monitoring gesendet. Wir sehen uns den aufgezeichneten Messwert später in diesem Codelab in der Firebase Console an.
Zweck von FirstDrawListener
Im obigen Abschnitt haben wir ein FirstDrawListener
registriert. Mit FirstDrawListener
wird gemessen, wann das Zeichnen des ersten Frames begonnen und beendet wurde.
Es implementiert ViewTreeObserver.OnDrawListener
und überschreibt den onDraw()
-Callback, der aufgerufen wird, wenn der Ansichtsbaum gezeichnet werden soll. Das Ergebnis wird dann in zwei Dienst-Callbacks onDrawingStart()
und onDrawingFinish()
verpackt.
Den vollständigen Code für FirstDrawListener
finden Sie im Quellcode dieses Codelab.
6. Ladezeit eines Fragments messen
Das Messen der Ladezeit eines Fragments ähnelt der Messung einer Aktivität, mit einigen geringfügigen Unterschieden. Wir instrumentieren wieder eine benutzerdefinierte Code-Spur:
- Überschreiben Sie den
onAttach()
-Callback und beginnen Sie mit der Aufzeichnung IhrerfragmentLoadTrace
. Wir nennen diesen TraceTest-Fragment-LoadTime
.
Wie in einem früheren Schritt erläutert, kann das Fragmentobjekt jederzeit erstellt werden, es wird jedoch erst aktiv, wenn es an die zugehörige Aktivität angehängt wird.
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");
}
- Registriere das
FirstDrawListener
imonViewCreated()
-Callback. Stoppen Sie dann, ähnlich wie im Aktivitätsbeispiel, den Trace inonDrawingFinish()
.
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();
}
});
- Führen Sie die App noch einmal aus. Filtern Sie dann den Logcat nach Logging trace metric. Tippe auf die Schaltfläche
LOAD FRAGMENT
und suche nach Protokollen wie unten:
I/FirebasePerformance: Logging trace metric: TestFragment-LoadTime (duration: XXXms)
🎉 Glückwunsch! Sie haben die Ladezeit eines Fragments erfolgreich gemessen und die Daten an Firebase Performance Monitoring gemeldet. Wir sehen uns den aufgezeichneten Messwert später in diesem Codelab in der Firebase Console an.
7. Bildschirmrendering und langsame/eingefrorene Frames
Beim UI-Rendering wird ein Frame aus Ihrer App generiert und auf dem Bildschirm dargestellt. Damit die Interaktion eines Nutzers mit Ihrer App reibungslos verläuft, sollte Ihre App Frames in weniger als 16 ms rendern, um 60 Bilder pro Sekunde zu erreichen. Warum sind es 60 fps? Wenn die Benutzeroberfläche Ihrer App langsam gerendert wird, wird das System gezwungen, Frames zu überspringen, und der Nutzer nimmt ein Ruckeln in Ihrer App wahr. Wir nennen dies Jack.
Eingefrorene Frames sind UI-Frames, deren Rendering länger als 700 ms dauert. Diese Verzögerung stellt ein Problem dar, da Ihre App während des Renderings des Frames fast eine ganze Sekunde lang nicht auf Nutzereingaben reagiert.
8. Langsame/eingefrorene Frames eines Fragments messen
Mit Firebase Performance Monitoring werden automatisch langsame/eingefrorene Frames für eine Aktivität erfasst (nur, wenn sie hardwarebeschleunigt ist). Für Fragmente ist diese Funktion derzeit jedoch nicht verfügbar. Die langsamen/eingefrorenen Frames eines Fragments werden als langsame/eingefrorene Frames für die gesamte Activity zwischen den onFragmentAttached()
- und onFragmentDetached()
-Callbacks im Lebenszyklus des Fragments definiert.
In Anlehnung an die AppStateMonitor
-Klasse (die Teil des Performance Monitoring SDK ist, das für die Aufzeichnung von Bildschirm-Traces für Aktivitäten verantwortlich ist), haben wir die ScreenTrace
-Klasse implementiert (Teil dieses Codelab-Quellcode-Repositorys). Die ScreenTrace
-Klasse kann mit dem Lebenszyklus-Callback der Aktivität FragmentManager
verknüpft werden, um langsame/eingefrorene Frames zu erfassen. Diese Klasse bietet zwei öffentliche APIs:
recordScreenTrace()
: Startet die Aufzeichnung eines Bildschirm-TracessendScreenTrace()
: Beendet die Aufzeichnung eines Bildschirm-Trace und fügt benutzerdefinierte Messwerte hinzu, um die Anzahl der Frames insgesamt, langsamer und eingefrorener Frames zu protokollieren
Wenn Sie diese benutzerdefinierten Messwerte anhängen, können Bildschirmaufzeichnungen für Fragmente genauso wie Bildschirmaufzeichnungen für eine Aktivität behandelt und zusammen mit anderen Bildschirm-Rendering-Aufzeichnungen im Dashboard „Leistung“ der Firebase Console angezeigt werden.
So protokollieren Sie Bildschirm-Traces für Ihr Fragment:
- Initialisieren Sie die
ScreenTrace
-Klasse in Ihrer Aktivität, die das Fragment hostet.
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);
// ...
}
- Registriere dich beim Laden des Fragments für
FragmentLifecycleCallbacks
und überschreibe dieonFragmentAttached()
- undonFragmentDetached()
-Callbacks. Wir haben das für Sie erledigt. Sie müssen die Aufzeichnung von Bildschirmaufzeichnungen imonFragmentAttached()
-Callback starten und imonFragmentDetached()
-Callback beenden.
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);
}
};
- Starten Sie die App noch einmal und tippen Sie dann auf die Schaltfläche
LOAD FRAGMENT
. Warten Sie einige Sekunden und klicken Sie dann in der unteren Navigationsleiste auf dasback button
.
Filtern Sie den Logcat mit „Logging trace metric“ und suchen Sie dann nach Protokollen wie den folgenden:
I/FirebasePerformance: Logging trace metric: _st_MainActivity-TestFragment (duration: XXXms)
Filtern Sie den Logcat mit „FireperfViews“ und suchen Sie dann nach Protokollen wie dem folgenden:
D/FireperfViews: sendScreenTrace MainActivity-TestFragment, name: _st_MainActivity-TestFragment, total_frames: XX, slow_frames: XX, frozen_frames: XX
🎉 Glückwunsch! Sie haben die langsamen/eingefrorenen Frames für ein Fragment gemessen und diese Daten an Firebase Performance Monitoring gesendet. Wir sehen uns die aufgezeichneten Messwerte später in diesem Codelab in der Firebase Console an.
9. Messwerte in der Firebase Console prüfen
- Klicken Sie in Logcat auf die Firebase Console-URL, um die Detailseite eines Logs aufzurufen.
Alternativ können Sie in der Firebase Console das Projekt mit Ihrer App auswählen. Suchen Sie im linken Bereich den Link Release & Überwachen und dann auf Leistung.
- Scrollen Sie auf dem Haupt-Tab Dashboard nach unten zur Traces-Tabelle und klicken Sie dann auf den Tab Benutzerdefinierte Traces. In dieser Tabelle sehen Sie die zuvor hinzugefügten benutzerdefinierten Code-Traces sowie einige vordefinierte Traces, z. B. den
_app_start
-Trace. - Suchen Sie die beiden benutzerdefinierten Codetraces
TestActivity-LoadTime
undTestFragment-LoadTime
. Klicken Sie für einen Eintrag auf die Dauer, um weitere Details zu den erhobenen Daten aufzurufen.
- Auf der Detailseite für den benutzerdefinierten Code-Trace werden Informationen zur Dauer des Trace (d.h. die gemessene Ladezeit) angezeigt.
- Sie können sich auch die Leistungsdaten für Ihren benutzerdefinierten Bildschirmaufruf ansehen.
- Kehren Sie zum Haupttab Dashboard zurück, scrollen Sie nach unten zur Traces-Tabelle und klicken Sie auf den Tab Bildschirmrendering. In dieser Tabelle sehen Sie die benutzerdefinierten Bildschirmaufzeichnungen, die wir zuvor hinzugefügt haben, sowie alle vordefinierten Bildschirmaufzeichnungen, z. B. die
MainActivity
-Aufzeichnung. - Suchen Sie Ihren benutzerdefinierten Bildschirm-Trace,
MainActivity-TestFragment
. Klicken Sie auf den Trace-Namen, um die aggregierten Daten zu langsamem Rendering und eingefrorenen Frames aufzurufen.
10. Glückwunsch
Glückwunsch! Sie haben mithilfe von Firebase Performance Monitoring die Ladezeit und die Bildschirm-Rendering-Leistung einer Aktivität und eines Fragments erfolgreich gemessen.
Das hast du erreicht
- Sie haben Firebase Performance Monitoring in eine Beispiel-App integriert.
- Sie kennen jetzt den Lebenszyklus des Ladens von Ansichten
- Sie haben die Ladezeit sowohl einer Aktivität als auch eines Fragments gemessen, indem Sie benutzerdefinierte Code-Traces hinzugefügt haben.
- Sie haben langsame/eingefrorene Frames aufgezeichnet, indem Sie benutzerdefinierte Bildschirm-Traces mit benutzerdefinierten Messwerten hinzugefügt haben.
Nächste Schritte
Firebase Performance bietet neben benutzerdefinierten Traces noch weitere Möglichkeiten zur Leistungsmessung Ihrer App. Es werden automatisch App-Startzeit, App-Leistung im Vordergrund und App-Leistung im Hintergrund gemessen. Als Nächstes überprüfen Sie diese Messwerte in der Firebase Console.
Firebase Performance bietet außerdem automatisches Monitoring von HTTP/S-Netzwerkanfragen. Damit können Sie Netzwerkanfragen ganz einfach instrumentieren, ohne eine einzige Codezeile schreiben zu müssen. Können Sie einige Netzwerkanfragen von Ihrer App senden und die Messwerte in der Firebase Console finden?
Bonus
Da Sie jetzt wissen, wie Sie die Ladezeit und die Bildschirmdarstellungsleistung Ihrer Aktivität/Ihres Fragments mithilfe benutzerdefinierter Code-Traces messen, können Sie unseren Open-Source-Code-Base untersuchen, um zu sehen, ob Sie diese Messwerte direkt für jede Aktivität/Fragment erfassen können, die Teil der App ist. Wenn Sie möchten, können Sie die PR-Datei auch gern senden.
11. Bonus-Lerninhalte
Wenn du weißt, was während des Ladens einer Aktivität passiert, kannst du die Leistungsmerkmale deiner App besser nachvollziehen. In einem früheren Schritt haben wir allgemein beschrieben, was während des Ladens einer Aktivität passiert. Im folgenden Diagramm werden die einzelnen Phasen jedoch viel ausführlicher beschrieben.