Beim Starten der App wird der erste Eindruck bei den Nutzern erzeugt. Apps müssen schnell starten und Informationen laden und anzeigen, die der Nutzer für die Verwendung der App benötigt. Wenn der Start zu lange dauert, beenden Nutzer die App möglicherweise, weil sie zu lange warten müssen.
Wir empfehlen, die Macrobenchmark-Bibliothek zu verwenden, um den Start zu messen. Die Bibliothek bietet einen Überblick und detaillierte System-Traces, um genau zu sehen, was beim Start passiert.
System-Traces liefern nützliche Informationen darüber, was auf Ihrem Gerät passiert. So können Sie nachvollziehen, was Ihre App beim Start tut, und potenzielle Optimierungsbereiche identifizieren.
So analysieren Sie den Start Ihrer App:
- Richten Sie eine Umgebung ein, um Traces für den App-Start aufzuzeichnen.
- System-Traces
- Sie können einen Trace-Bericht mit den Android Studio Profilers oder Perfetto aufrufen.
Schritte zum Analysieren und Optimieren des Startvorgangs
Apps müssen beim Start oft bestimmte Ressourcen laden, die für Endnutzer wichtig sind. Nicht essenzielle Ressourcen können erst nach Abschluss des Startvorgangs geladen werden.
Berücksichtigen Sie bei der Entscheidung für Leistungskompromisse Folgendes:
Verwenden Sie die Macrobenchmark-Bibliothek, um die für jeden Vorgang benötigte Zeit zu messen und Blöcke zu identifizieren, die lange dauern.
Prüfen Sie, ob der ressourcenintensive Vorgang für den Start der App erforderlich ist. Wenn der Vorgang warten kann, bis die App vollständig gerendert wurde, können Ressourcenbeschränkungen beim Start minimiert werden.
Prüfen Sie, ob dieser Vorgang beim Start der App ausgeführt werden soll. Häufig werden unnötige Vorgänge aus Legacy-Code oder Bibliotheken von Drittanbietern aufgerufen.
Verschieben Sie Vorgänge mit langer Ausführungszeit nach Möglichkeit in den Hintergrund. Hintergrundprozesse können sich weiterhin auf die CPU-Auslastung beim Start auswirken.
Nachdem Sie den Vorgang vollständig untersucht haben, können Sie entscheiden, ob Sie ihn in den App-Start einbeziehen möchten. Denken Sie daran, dass bei Änderungen am Workflow Ihrer App das Risiko von Regressionen oder Breaking Changes besteht.
Optimieren Sie die App und führen Sie die Messung noch einmal durch, bis Sie mit der Startzeit zufrieden sind. Weitere Informationen finden Sie unter Messwerte zum Erkennen und Diagnostizieren von Problemen verwenden.
Zeitaufwand für wichtige Vorgänge messen und analysieren
Wenn Sie einen vollständigen App-Start-Trace haben, sehen Sie sich den Trace an und messen Sie die Zeit, die für wichtige Vorgänge wie bindApplication oder activityStart benötigt wird. Wir empfehlen, diese Traces mit Perfetto oder den Android Studio Profilers zu analysieren.
Sehen Sie sich die Gesamtzeit an, die beim Starten der App benötigt wird, um Vorgänge zu identifizieren, die Folgendes tun:
- Sie nehmen viel Zeit in Anspruch und können optimiert werden. Bei der Leistung zählt jede Millisekunde. Suchen Sie beispielsweise nach
Choreographer-Zeiten für das Rendern, Zeiten für die erste Komposition, Zeiten für das Laden der Bibliothek,Binder-Transaktionen oder Zeiten für das Laden von Ressourcen. Sehen Sie sich zuerst alle Vorgänge an, die länger als 20 ms dauern. - Blockieren Sie den Hauptthread. Weitere Informationen finden Sie unter Systrace-Bericht verwenden.
- Müssen nicht beim Start ausgeführt werden.
- Kann bis nach dem Zeichnen des ersten Frames warten.
Untersuchen Sie die einzelnen Traces genauer, um Leistungsprobleme zu finden.
Aufwendige Vorgänge im Haupt-Thread identifizieren
Es empfiehlt sich, rechenintensive Vorgänge wie Datei-E/A und Netzwerkzugriff nicht im Hauptthread auszuführen. Das ist auch beim Starten der App wichtig, da rechenintensive Vorgänge im Hauptthread dazu führen können, dass die App nicht mehr reagiert und andere wichtige Vorgänge verzögert werden.
StrictMode.ThreadPolicy kann helfen, Fälle zu identifizieren, in denen rechenintensive Vorgänge im Hauptthread ausgeführt werden.
Es empfiehlt sich, StrictMode in Debug-Builds zu aktivieren, um Probleme so früh wie möglich zu erkennen. Das folgende Beispiel zeigt, wie das geht:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
...
if (BuildConfig.DEBUG)
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyDeath()
.build()
)
...
}
}
Durch die Verwendung von StrictMode.ThreadPolicy wird die Thread-Richtlinie für alle Debug-Builds aktiviert und die App stürzt ab, sobald Verstöße gegen die Thread-Richtlinie erkannt werden. Dadurch ist es schwierig, Verstöße gegen die Thread-Richtlinie zu übersehen.
TTID und TTFD
Um die Zeit zu ermitteln, die die App zum Rendern des ersten Frames benötigt, messen Sie die Zeit bis zur ersten Anzeige (Time to Initial Display, TTID). Dieser Messwert gibt jedoch nicht unbedingt an, wie lange es dauert, bis der Nutzer mit Ihrer App interagieren kann. Der Messwert Zeit bis zur vollständigen Darstellung (Time to Full Display, TTFD) ist nützlicher, um die Codepfade zu messen und zu optimieren, die für einen vollständig nutzbaren App-Status erforderlich sind.
Strategien für das Melden, wenn die App-Benutzeroberfläche vollständig gerendert wurde, finden Sie unter Genauigkeit des Startzeitpunkts verbessern.
Optimieren Sie sowohl für TTID als auch für TTFD, da beide in ihren jeweiligen Bereichen wichtig sind. Eine kurze TTID hilft dem Nutzer zu erkennen, dass die App tatsächlich gestartet wird. Eine kurze TTFD ist wichtig, damit der Nutzer schnell mit der App interagieren kann.
Gesamt-Threadstatus analysieren
Wählen Sie die App-Startzeit aus und sehen Sie sich die gesamten Thread-Abschnitte an. Der Hauptthread muss jederzeit reagieren.
Tools wie der Android Studio Profiler und Perfetto bieten einen detaillierten Überblick über den Hauptthread und darüber, wie viel Zeit in jeder Phase verbracht wird. Weitere Informationen zum Visualisieren von Perfetto-Traces finden Sie in der Dokumentation zur Perfetto-Benutzeroberfläche.
Wichtige Abschnitte des Schlafzustands des Hauptthreads identifizieren
Wenn viel Zeit mit dem Schlaf verbracht wird, liegt das wahrscheinlich daran, dass der Hauptthread Ihrer App darauf wartet, dass die Arbeit abgeschlossen wird. Wenn Sie eine Multithread-App haben, ermitteln Sie den Thread, auf den Ihr Hauptthread wartet, und optimieren Sie diese Vorgänge. Außerdem können Sie so feststellen, ob es unnötige Konflikte bei der Sperrung gibt, die zu Verzögerungen im kritischen Pfad führen.
Blockierung des Hauptthreads und nicht unterbrechbaren Schlaf reduzieren
Suchen Sie nach jeder Instanz, in der der Hauptthread in einen blockierten Zustand wechselt. In Perfetto und Studio Profiler wird dies durch eine orangefarbene Markierung auf der Zeitachse für den Threadstatus angezeigt. Identifizieren Sie die Vorgänge, prüfen Sie, ob sie erwartet werden oder vermieden werden können, und optimieren Sie sie bei Bedarf.
E/A-bezogener unterbrechbarer Schlaf kann eine sehr gute Möglichkeit zur Verbesserung sein. Andere Prozesse, die E/A-Vorgänge ausführen, auch wenn es sich um nicht verwandte Apps handelt, können mit den E/A-Vorgängen der Top-App konkurrieren.
Startzeit verbessern
Nachdem Sie eine Optimierungsmöglichkeit ermittelt haben, sollten Sie sich mögliche Lösungen ansehen, um die Startzeiten zu verbessern:
- Laden Sie Inhalte verzögert und asynchron, um die TTID zu beschleunigen.
- Minimieren Sie Aufrufe von Funktionen, die Binder-Aufrufe ausführen. Wenn sie unvermeidlich sind, sollten Sie diese Aufrufe optimieren, indem Sie Werte im Cache speichern, anstatt Aufrufe zu wiederholen oder nicht blockierende Aufgaben in Hintergrundthreads zu verschieben.
- Damit der Start Ihrer App schneller erscheint, können Sie dem Nutzer so schnell wie möglich etwas anzeigen, das nur minimales Rendern erfordert, bis der Rest des Bildschirms geladen ist.
- Erstellen Sie ein Startprofil und fügen Sie es Ihrer App hinzu.
- Mit der Jetpack-Bibliothek App Startup können Sie die Initialisierung von Komponenten beim App-Start optimieren.
UI-Leistung analysieren
Der App-Start umfasst einen Ladebildschirm und die Ladezeit Ihrer Startseite. Um den App-Start zu optimieren, sollten Sie Traces untersuchen, um die Zeit zu ermitteln, die zum Zeichnen der Benutzeroberfläche benötigt wird.
Arbeit bei der Initialisierung begrenzen
Das Laden bestimmter Frames kann länger dauern als das anderer. Diese gelten als teure Zeichenvorgänge für die App.
So optimieren Sie die Initialisierung:
- Priorisieren Sie langsame Phasen für Komposition und Layout und wählen Sie diese für Verbesserungen aus.
- Untersuchen Sie jede Warnung von Perfetto und jede Benachrichtigung von Systrace, indem Sie benutzerdefinierte Trace-Ereignisse hinzufügen, um teure Zeichenvorgänge und Verzögerungen zu reduzieren.
Frame-Daten analysieren
Es gibt mehrere Möglichkeiten, Framedaten zu erfassen. Die fünf wichtigsten Erhebungsmethoden sind:
- Lokale Erhebung mit
dumpsys gfxinfo:Nicht alle Frames, die in den dumpsys-Daten beobachtet werden, sind für das langsame Rendern Ihrer App verantwortlich oder haben Auswirkungen auf Endnutzer. Er ist jedoch ein guter Messwert, um die allgemeine Leistungsentwicklung über verschiedene Release-Zyklen hinweg zu beobachten. Weitere Informationen zur Verwendung vongfxinfoundframestatszum Einbinden von UI-Leistungsmessungen in Ihre Testverfahren finden Sie unter Grundlagen des Testens von Android-Apps. - Erfassung von Feldern mit JankStats:Mit der JankStats-Bibliothek können Sie die Frame-Renderzeiten für bestimmte Teile Ihrer App erfassen und die Daten aufzeichnen und analysieren.
- Bei Tests mit Macrobenchmark (Perfetto im Hintergrund)
- Perfetto FrameTimeline:Unter Android 12 (API-Level 31) oder höher können Sie Messwerte für die Frame-Zeitleiste aus einem Perfetto-Trace erfassen, um zu ermitteln, welche Aufgabe den Frame-Drop verursacht. Das kann der erste Schritt sein, um herauszufinden, warum Frames ausgelassen werden.
- Android Studio Profiler für die Erkennung von Rucklern
Ladezeit der Hauptaktivität prüfen
Die Hauptaktivität Ihrer App enthält möglicherweise eine große Menge an Informationen, die aus mehreren Quellen geladen werden. Sehen Sie sich die Activity-Benutzeroberfläche für das Zuhause an, insbesondere das Choreographer#doFrame-Ereignis.
- Verwenden Sie
reportFullyDrawn, um dem System mitzuteilen, dass Ihre App jetzt vollständig gerendert wurde und optimiert werden kann. - Mit der Macrobenchmark-Bibliothek können Sie Aktivitäten und App-Starts mit
StartupTimingMetricmessen. - Achten Sie auf Frame-Drops.
- Layouts identifizieren, deren Rendering oder Messung lange dauert.
- Assets identifizieren, die lange zum Laden benötigen
- Identifizieren Sie unnötige UI-Elemente, die in der ursprünglichen Komposition enthalten sind.
Hier sind einige mögliche Lösungen zur Optimierung der Ladezeit der Hauptaktivität:
- Gestalten Sie die erste Komposition so einfach wie möglich. Weitere Informationen finden Sie unter Jetpack Compose-Leistung.
- Fügen Sie benutzerdefinierte Tracepoints hinzu, um weitere Informationen zu verworfenen Frames und komplexen Layouts zu erhalten.
- Minimieren Sie die Anzahl und Größe der Bitmap-Ressourcen, die beim Start geladen werden. Weitere Informationen finden Sie unter Bitmap-Bilder optimieren.
Wenn Sie Jetpack Compose verwenden, sollten Sie die bedingte Komposition in Betracht ziehen, um das Laden von Teilen der Benutzeroberfläche zu verzögern, die beim Start nicht sofort sichtbar sind, z. B. Fehlerbildschirme, optionale Details oder sekundäre Tabs. Wenn Sie rechenintensive Komponenten in eine einfache Statusprüfung einbetten, vermeiden Sie die Ausführung ihrer Kompositionslogik während des kritischen Startzeitfensters und halten Ihr anfängliches Layout schlank.
var shouldLoad by remember {mutableStateOf(false)} if (shouldLoad) { MyComposable() }Laden Sie die Composables im bedingten Block, indem Sie
shouldLoadändern:LaunchedEffect(Unit) { shouldLoad = true }Dadurch wird eine Neukomposition ausgelöst, die den Code im bedingten Block im ersten Snippet enthält.
Weitere Informationen zur Optimierung der Compose-Leistung finden Sie unter Best Practices.
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Makrobenchmark-Messwerte erfassen
- Übersicht über die Messung der App-Leistung * Eingefrorene Frames