In diesem Dokument erfährst du, wie du wichtige Leistungsprobleme deiner App erkennen und beheben kannst.
Wichtige Leistungsprobleme
Es gibt viele Probleme, die zu einer schlechten Leistung einer App führen können,
Im Folgenden sind einige häufige Probleme aufgeführt, nach denen Sie in Ihrer App Ausschau halten sollten:
Die Startlatenz ist die Zeit, die zwischen dem Antippen der App vergeht
das Symbol, die Benachrichtigung oder einen anderen Einstiegspunkt hat und die Daten des Nutzers
Bildschirm.
Folgende Ziele für Start-ups sollten in Ihren Apps angestrebt werden:
Kaltstart in weniger als 500 ms. Ein Kaltstart findet statt, wenn die App
nicht im Arbeitsspeicher des Systems vorhanden ist. Das passiert, wenn es
Der erste Start der App seit dem Neustart oder seit dem Beenden des App-Prozesses
vom Nutzer oder vom System.
Ein Warmstart findet hingegen statt, wenn die App bereits in
im Hintergrund. Ein Kaltstart erfordert die meiste Arbeit im System,
muss alles aus dem Speicher geladen
und die App initialisiert werden. Versuchen Sie,
damit Kaltstarts 500 ms oder weniger dauern.
Die P95- und P99-Latenzen liegen sehr nahe an der Medianlatenz. Wenn die App
lange am Anfang dauert, ist die User Experience
schlecht.
Interprocess Communication (IPCs) und unnötige E/A-Vorgänge während
kann es beim Start der App zu
Sperrkonflikten kommen
zu Inkonsistenzen führen.
Mit dem Begriff Jank wird der visuelle Schluckauf beschrieben, der auftritt, wenn die
nicht in der Lage ist, Frames zu erstellen und rechtzeitig bereitzustellen,
Bildschirm mit der gewünschten Frequenz von 60 Hz oder höher. Schwankungen treten am deutlichsten auf,
beim Scrollen statt beim animierten Ablauf kommt es zu Problemen. Ruck
erscheint, wenn die Bewegung für einen oder mehrere Frames auf dem Weg pausiert, während das
Das Rendern des Inhalts durch eine App ist länger als die Dauer eines Frames auf dem System.
Apps müssen auf eine Aktualisierungsrate von 90 Hz ausgerichtet sein. Herkömmliche Renderingraten betragen 60 Hz,
Neuere Geräte arbeiten jedoch bei Nutzerinteraktionen im 90-Hz-Modus,
wie Scrollen. Einige Geräte unterstützen sogar noch höhere Frequenzen von bis zu 120 Hz.
Um zu sehen, welche Aktualisierungsrate ein Gerät zu einem bestimmten Zeitpunkt verwendet, aktivieren Sie eine
mithilfe von Entwickleroptionen > Aktualisierungsrate unter Debugging anzeigen
.
Nicht reibungslose Übergänge
Dies wird bei Interaktionen wie dem Wechseln zwischen Tabs oder beim Laden von
einer neuen Aktivität. Diese Übergänge müssen flüssige Animationen sein,
z. B. Verspätungen oder
Flimmern.
Ineffizienzen bei der Stromversorgung
Durch Arbeit wird der Akku geschont, während unnötige Arbeiten den Akku schonen.
Leben.
Speicherzuweisungen, die durch das Erstellen neuer Objekte im Code entstehen, können
Ursache erheblicher Arbeit im System zu finden. Das liegt daran, dass nicht nur die
die Zuweisung selbst erfordert einen Aufwand für Android Runtime (ART), aber
die spätere Freigabe dieser Objekte (automatische Speicherbereinigung) erfordert ebenfalls Zeit und
zu konzentrieren. Sowohl die Zuweisung als auch die Erfassung
sind viel schneller und effizienter.
insbesondere für temporäre Objekte. Früher war es Best Practice,
sollten möglichst keine Objekte zugewiesen werden.
für Ihre App und Architektur am sinnvollsten ist. Einsparungen bei Zuweisungen in
Das Risiko nicht verwaltbarer Codes ist aufgrund der ART-Methode nicht die Best Practice.
Dies ist jedoch mit Aufwand verbunden, denken Sie also daran,
wenn Sie viele Objekte
in Ihrer inneren Schleife zuweisen.
Probleme erkennen
Wir empfehlen den folgenden Workflow, um Leistungsprobleme zu identifizieren und zu beheben:
Identifizieren und prüfen Sie die folgenden kritischen User Journeys:
<ph type="x-smartling-placeholder">
</ph>
Gängige Startabläufe, auch über den Launcher und Benachrichtigungen.
Bildschirme, auf denen der Nutzer durch Daten scrollt.
Übergänge zwischen Bildschirmen.
Lang andauernde Abläufe wie Navigation oder Musikwiedergabe
Prüfen Sie mit folgendem Befehl, was in den vorherigen Abläufen passiert:
Debugging-Tools:
<ph type="x-smartling-placeholder">
</ph>
Perfetto: Damit können Sie sehen, was auf dem gesamten Gerät passiert.
mit genauen Zeitdaten.
Memory Profiler: Damit können Sie feststellen, welche Arbeitsspeicherzuweisungen erfolgen
auf dem Heap.
Simpleperf: zeigt ein Flamegraph für welche Funktionsaufrufe das
die meiste CPU-Leistung während
eines bestimmten Zeitraums nutzen. Wenn Sie etwas
Das dauert in Systrace sehr lange, aber Sie wissen nicht warum, Simpleperf.
kann zusätzliche Informationen liefern.
Um diese Leistungsprobleme zu verstehen und zu beheben, ist es wichtig,
Fehler in einzelnen Testläufen zu beheben. Sie können die vorherigen Schritte nicht durch folgende Analyse ersetzen:
aggregierte Daten. Um jedoch zu verstehen, was Nutzende tatsächlich sehen
erkennen, wann Regressionen auftreten können, ist es wichtig, Messwerte einzurichten,
bei automatischen Tests und im Praxisbereich:
Play Console-Frame Vitals: In der Play Console lässt sich die
Messwerte bis hin zu einer
bestimmten User Journey. Es werden nur Verzögerungen gemeldet.
in der gesamten App.
Benutzerdefinierte Messung mit FrameMetricsAggregator: Sie können Folgendes verwenden:
FrameMetricsAggregator, um Verzögerungsmesswerte während einer bestimmten
zu optimieren.
MacroBenchmark erfasst das Frame-Timing mit dumpsys gfxinfo-Befehlen
die eine einzelne User Journey umfassen. Auf diese Weise können Sie
Verzögerung in einer bestimmten User Journey. Das RenderTime
Messwerte, die angeben, wie lange das Zeichnen von Frames dauert,
als die Anzahl der instabilen Frames, um Regressionen zu erkennen
oder Verbesserungen vorzunehmen.
Probleme bei der Bestätigung von App-Links
App-Links sind Deeplinks, die auf Ihrer Website-URL basieren und für
die zu Ihrer Website gehören. App-Links können folgende Ursachen haben:
dass die Überprüfungen fehlschlagen.
Intent-Filterbereiche: Fügen Sie autoVerify zu Intent-Filtern nur für URLs hinzu, die
auf die deine App reagieren kann.
Nicht verifizierte Protokoll-Switches: nicht bestätigte Server- und Subdomain-Weiterleitungen
als Sicherheitsrisiken gelten und die Prüfung nicht bestehen. Sie sorgen dafür,
Fehler bei autoVerify Verknüpfungen. Wenn Sie beispielsweise Links von HTTP zu HTTPS weiterleiten,
wie beispiel.de zu www.beispiel.de, ohne dass die HTTPS-Links überprüft werden,
die Überprüfung fehlschlägt. Bestätigen Sie App-Links, indem Sie einen Intent hinzufügen.
Filter.
Nicht überprüfbare Links: Wenn Sie nicht überprüfbare Links zu Testzwecken hinzufügen,
führen dazu, dass das System die App-Links für Ihre App nicht überprüft.
Unzuverlässige Server: Stellen Sie sicher, dass Ihre Server eine Verbindung zu Ihren Client-Apps herstellen können.
App für Leistungsanalysen einrichten
Eine korrekte Einrichtung ist wichtig, um präzise, wiederholbare und umsetzbare
Benchmarks aus einer App. Testen Sie auf einem System, das sich so nah an der Produktion befindet wie
während Rauschquellen unterdrückt werden. Die folgenden Abschnitte enthalten eine
Anzahl der APK- und systemspezifischen Schritte, die Sie unternehmen können, um eine Testeinrichtung vorzubereiten.
von denen einige anwendungsfallspezifisch sind.
Während Traces erfasst werden, verursacht das Tracing einen geringen Overhead von etwa
5 μs pro Bereich, also nicht für jede Methode. Tracing größerer Blöcke
von > 0,1 ms können wichtige Erkenntnisse zu Engpässen liefern.
Überlegungen zum APK
Debug-Varianten können hilfreich sein,
um Fehler zu beheben und Stackproben zu symbolisieren,
aber sie haben erhebliche Auswirkungen auf die Leistung. Geräte mit Android 10 (API)
ab Level 29) profileable android:shell="true" in ihrem eigenen
Manifest erstellt, um die Profilerstellung in Release-Builds zu aktivieren.
Verwenden Sie Ihre produktionstaugliche Konfiguration zur Codereduzierung. Je nach
Ressourcen, die Ihre App verwendet, kann dies erhebliche Auswirkungen auf die Leistung haben. Einige
ProGuard-Konfigurationen werden Tracepunkte entfernt. Sie sollten diese Regeln
die Konfiguration, mit der Sie Tests ausführen.
Compilation
Kompiliere deine App auf dem Gerät zu einem bekannten Zustand, in der Regel speed oder
speed-profile. JIT-Aktivitäten (Just-in-Time) im Hintergrund können beträchtliche
und dies häufig durch eine Neuinstallation des APK
zwischen den Testläufen. Dazu verwenden Sie den folgenden Befehl:
Die Anwendung wird im speed-Kompilierungsmodus vollständig kompiliert. Das speed-profile
Modus kompiliert die App anhand eines Profils der verwendeten Codepfade,
die während der App-Nutzung erfasst werden. Es kann schwierig sein, Profile einheitlich zu erfassen.
und korrekt sind. Wenn Sie sich für einen Einsatz
entscheiden, vergewissern Sie sich, dass sie Daten erheben,
die Sie erwarten. Die Profile befinden sich an folgendem Ort:
Kalibrieren Sie Ihre Geräte für Low-Level- und High-Fidelity-Messungen. A/B ausführen
Vergleiche für dasselbe Gerät und dieselbe Betriebssystemversion. Es können erhebliche
auch auf verschiedenen Gerätetypen.
Auf gerooteten Geräten bietet es sich an, ein lockClocks-Script für
Mikro-Benchmarks: Diese Scripts erledigen unter anderem Folgendes:
Platzieren Sie CPUs mit einer festen Frequenz.
Deaktivieren Sie kleine Kerne und konfigurieren Sie die GPU.
Energiedrosselung deaktivieren.
Für Tests zur Nutzererfahrung raten wir davon ab, das Skript lockClocks zu verwenden.
wie App-Einführung, DoU-Tests und Verzögerungstests. Sie können jedoch für
zur Reduzierung von Rauschen in MicroBenchmark-Tests.
Verwenden Sie nach Möglichkeit ein Testframework wie MacroBenchmark,
wodurch Rauschen in den Messwerten reduziert und Messungenauigkeiten verhindert werden.
Langsamer App-Start: unnötige Trampolinaktivität
Eine Trampolinaktivität kann die Startzeit der App unnötig verlängern,
sollten Sie sich darüber im Klaren sein,
ob Ihre App dies tut. Hier ein Beispiel:
Trace wird unmittelbar auf ein activityStart gefolgt von einem anderen activityStart.
ohne dass Frames von der ersten Aktivität gezeichnet wurden.
Abbildung 1: Eine Spur, die eine Trampolinaktivität zeigt.
Dies kann sowohl bei einem Benachrichtigungseinstiegspunkt als auch beim regulären App-Start vorkommen
und lässt sich oft durch Refaktorierung beheben. Wenn Sie zum Beispiel
mit dieser Aktivität einrichten, bevor eine andere Aktivität ausgeführt wird.
in eine wiederverwendbare Komponente
oder Bibliothek übertragen.
Unnötige Zuweisungen, die häufige GCs auslösen
Sie werden feststellen, dass die automatische Speicherbereinigung häufiger erfolgt als Sie
was in einem Systrace zu erwarten ist.
Im folgenden Beispiel wird alle 10 Sekunden während eines lang andauernden Vorgangs
ein Hinweis darauf, dass die App Zuweisungen unnötigerweise,
Zeit:
Abbildung 2: Ein Trace, das Leerzeichen zwischen GC-Ereignissen zeigt.
Sie werden auch feststellen, dass ein bestimmter Aufrufstack den Großteil der
bei Verwendung des Memory Profiler. Sie müssen nicht alle
Zuweisungen aggressiv, da dies die Wartung des Codes erschweren kann. Stattdessen
mit Hotspots der Zuweisung beginnen.
Ruckelnde Rahmen
Die Grafikpipeline ist relativ kompliziert und es kann Nuancen bei der
Es wird bestimmt, ob ein Nutzer einen ausgelassenen Frame sehen kann. In einigen Fällen
kann die Plattform „Rettung“ einen Frame mit Pufferung. Die meisten Seiten können Sie jedoch
um problematische Frames aus
der Perspektive Ihrer App zu identifizieren.
Wenn Frames mit wenig Aufwand von der App gezeichnet werden,
Choreographer.doFrame() Tracepoints treten in einer Frequenz von 16,7 ms bei 60 fps auf
Gerät:
Abbildung 3: Ein Trace, das häufige schnelle Frames zeigt.
Wenn Sie herauszoomen und durch die Trace navigieren, sehen Sie manchmal, dass Frames einen
etwas länger dauern, aber es ist trotzdem in Ordnung, da sie nicht
als die zugeteilte Zeit von 16,7 ms zu?
Abbildung 4: Trace, das häufige schnelle Frames mit periodischen Bursts von
arbeiten.
Wenn du eine Unterbrechung dieser Frequenz siehst, ist dies ein ruckeliges Bild (siehe Abbildung).
in Abbildung 5:
Abbildung 5: Eine Spur, die einen ruckeligen Frame zeigt.
Sie können üben, sie zu identifizieren.
Abbildung 6: Ein Trace, das mehr instabile Frames zeigt.
In einigen Fällen müssen Sie einen Tracepoint heranzoomen, um weitere Informationen
welche Aufrufe überhöht werden oder was RecyclerView tut. In anderen Fällen
müssen Sie sie möglicherweise
weiter untersuchen.
Weitere Informationen zur Identifizierung von fehlerhaften Frames und zur Fehlerbehebung
Siehe Langsames Rendering.
Häufige RecyclerView-Fehler
Wenn alle Sicherungsdaten von RecyclerView unnötigerweise entwertet werden,
zu langen Frame-Renderingzeiten und Verzögerungen führen. Um stattdessen die Anzahl der
Datenansichten, die aktualisiert werden müssen, werden nur die Daten ungültig, die sich ändern.
Unter Dynamische Daten präsentieren erfahren Sie, wie Sie teure notifyDatasetChanged() vermeiden können.
-Aufrufen, die dazu führen, dass Inhalte aktualisiert werden, anstatt sie vollständig zu ersetzen.
Wenn nicht alle verschachtelten RecyclerView-Elemente ordnungsgemäß unterstützt werden, kann dies dazu führen,
interne RecyclerView, die jedes Mal vollständig neu erstellt werden. Jede verschachtelte,
Für die innere RecyclerView muss RecycledViewPool festgelegt sein, damit
Ansichten können zwischen jedem inneren RecyclerView wiederverwendet werden.
Wenn nicht genügend Daten im Voraus abgerufen werden oder diese nicht rechtzeitig abgerufen werden,
das Ende einer scrollbaren Liste erreicht, ist es verwirrend, wenn Nutzende auf
mehr Daten vom Server zu erhalten. Auch wenn dies im Prinzip keine Verzögerung ist,
Fristen versäumt werden, können Sie die UX erheblich verbessern, indem Sie
Zeit und Menge des Vorabrufs, damit die Nutzenden nicht auf
Daten.
App-Fehler beheben
Im Folgenden finden Sie verschiedene Methoden, um Fehler in der Leistung Ihrer App zu beheben. Weitere Informationen finden Sie unter
Das folgende Video bietet einen Überblick über die Systemverfolgung und die Verwendung der
Studio-Profiler.
Fehler beim Starten der Anwendung mit Systrace beheben
Einen Überblick über den App-Startvorgang erhalten Sie unter App-Startzeit. Siehe
Im folgenden Video erhalten Sie einen Überblick über das System-Tracing.
Sie können Start-up-Typen in den folgenden Phasen unterscheiden:
Warmer Start: erstellt entweder die Aktivität neu, während der Prozess wiederverwendet wird, oder
erstellt den Prozess mit dem gespeicherten Zustand neu.
Heißstart: Die Aktivität wird neu gestartet und beginnt bei Inflation.
Konflikte beobachten: Der Wettbewerb um Monitor-geschützte Ressourcen kann zu
deutliche Verzögerung beim App-Start.
Synchrone Binder-Transaktionen: Suchen Sie nach unnötigen Transaktionen in Ihrem
den kritischen Pfad einer App. Wenn eine notwendige Transaktion teuer ist, sollten Sie in Betracht ziehen,
mit dem zugehörigen Plattformteam zusammen,
um Verbesserungen vorzunehmen.
Gleichzeitige Speicherbereinigung: Dies ist eine häufige und relativ geringe Auswirkung. Wenn Sie jedoch
die Probleme auftreten, sollten Sie sich dies mit dem Android Studio Memory
Profiler.
E/A: Suchen nach E/A, die während des Starts durchgeführt wurden, und nach langen Wartezeiten.
Erhebliche Aktivität in anderen Threads: Diese können den UI-Thread beeinträchtigen,
also achten Sie beim Start auf
Hintergrundarbeiten.
Wir empfehlen, reportFullyDrawn aufzurufen, wenn der Start von
aus der Perspektive der App
für verbesserte Berichte zu App-Startmesswerten. Uhrzeit anzeigen
zur vollständigen Anzeige finden Sie weitere Informationen zur Verwendung von reportFullyDrawn.
Sie können RFD-definierte Startzeiten
über den Perfetto-Trace-Prozessor
und ein für den Nutzer
sichtbares Trace-Ereignis ausgegeben.
System-Tracing auf dem Gerät verwenden
Sie können die System-Tracing-App auf Systemebene verwenden, um ein System zu erfassen,
auf einem Gerät. Mit dieser App können Sie Traces vom Gerät aufzeichnen, ohne
sie an eine Steckdose anschließen oder mit adb verbinden.
Memory Profiler von Android Studio verwenden
Mit dem Memory Profiler von Android Studio können Sie die Arbeitsspeicherauslastung prüfen.
Speicherlecks oder schlechten
Nutzungsmustern verursacht werden. Sie bietet eine Live-
der Objektzuweisungen.
Sie können Speicherprobleme in Ihrer App beheben, indem Sie den Informationen in der
Memory Profiler, um zu verfolgen, warum und wie oft GCs auftreten.
Führen Sie die folgenden Schritte aus, um ein Profil für den App-Arbeitsspeicher zu erstellen:
Speicherprobleme erkennen.
Zeichnen Sie eine Sitzung mit einem Arbeitsspeicherprofil der User Journey auf, auf die Sie sich konzentrieren möchten.
Achten Sie auf eine steigende Objektanzahl (siehe Abbildung 7), die schließlich
zu Speicherbereinigungen, wie in Abbildung 8 dargestellt.
Abbildung 7: Objektanzahl wird erhöht.
Abbildung 8: Automatische Speicherbereinigung.
Nachdem Sie die User Journey identifiziert haben, die zu einer erhöhten Speicherauslastung führt,
für die Ursachen der Speicherauslastung.
Diagnose von Hotspots bei Speicherauslastung.
Wählen Sie einen Bereich auf der Zeitachse aus, um sowohl Zuweisungen als auch
Flache Größe, wie in Abbildung 9 dargestellt.
Abbildung 9: Werte für Allocations und Shallow
Größe:
Es gibt mehrere Möglichkeiten, diese Daten zu sortieren. Im Folgenden finden Sie einige Beispiele für
wie Sie mit jeder Ansicht
Probleme analysieren können.
Nach Kursen sortieren: Dies ist hilfreich, wenn Sie nach Kursen suchen möchten,
Generieren von Objekten, die ansonsten im Cache gespeichert oder aus einem Arbeitsspeicherpool wiederverwendet werden
Wenn Sie beispielsweise eine App sehen, die 2.000 Objekte der Klasse "class"
„Vertex“ wird die Anzahl der Allocations pro Sekunde um 2.000 erhöht.
und sehen es beim Sortieren nach Kurs. Wenn Sie die
einen Speicherpool implementieren, um unnötige Speicherbestände zu vermeiden.
Nach Aufrufstack sortieren: Dies ist hilfreich, wenn Sie herausfinden möchten, wo es Probleme mit der Funktion gibt.
Pfad, in dem Speicher zugewiesen wird, beispielsweise innerhalb einer Schleife oder einer
Funktion, die viel Zuweisungsarbeit übernimmt.
Flache Größe: Erfasst nur den Arbeitsspeicher des Objekts selbst. Es ist nützlich
zur Verfolgung einfacher Klassen, die ausschließlich aus primitiven Werten bestehen.
Beibehaltene Größe: Zeigt den Gesamtarbeitsspeicher aufgrund des Objekts und der Referenzen an.
die ausschließlich durch das Objekt referenziert wird. Sie ist nützlich, um den Speicher nachzuverfolgen
Druck aufgrund komplexer Objekte entstehen. Sie benötigen einen vollen Arbeitsspeicher, um diesen Wert zu erhalten
wie in Abbildung 10 gezeigt, und Behaltene Größe wird als Spalte hinzugefügt,
wie in Abbildung 11 dargestellt.
GCs sind deutlicher erkennbar und die Auswirkungen des Arbeitsspeichers sind leichter zu messen
Optimierungen vor. Wenn durch eine Optimierung die Speicherauslastung reduziert wird,
weniger Speicherbereinigungen.
Um die Auswirkungen der Optimierung zu messen, messen Sie in der Profiler-Zeitachse die
Zeit zwischen den Speicherbereinigungen. Sie können sehen, dass es zwischen den GCs länger dauert.
Die ultimativen Auswirkungen einer Verbesserung des Arbeitsspeichers sind folgende:
Das Herunterfahren von unzureichendem Arbeitsspeicher sinkt wahrscheinlich, wenn die App nicht ständig
dass die Speicherauslastung
überhaupt nicht ausreicht.
Weniger GCs verbessern die Verzögerungsmesswerte, insbesondere beim P99. Dies ist
da GCs CPU-Konflikte verursachen, was dazu führen kann,
während GC erfolgt.
Empfehlungen für dich
Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
Alle Inhalte und Codebeispiele auf dieser Seite unterliegen den Lizenzen wie im Abschnitt Inhaltslizenz beschrieben. Java und OpenJDK sind Marken oder eingetragene Marken von Oracle und/oder seinen Tochtergesellschaften.