Anwendungsleistung messen – Übersicht

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:

Latenz beim Starten

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.

Scrollverzögerung

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:

  1. 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
  2. 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:

  • Startvorgänge <ph type="x-smartling-placeholder">
  • Ruck <ph type="x-smartling-placeholder">
      </ph>
    • Feldmesswerte <ph type="x-smartling-placeholder">
        </ph>
      • 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.
    • Labortests <ph type="x-smartling-placeholder">
        </ph>
      • Scrollen mit MacroBenchmark:
      • 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.

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.

Trace-Punkte

Apps können ihren Code mit benutzerdefinierten Trace-Ereignissen instrumentieren.

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:

adb shell cmd package compile -m speed -f com.google.packagename

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:

/data/misc/profiles/ref/[package-name]/primary.prof

Mit MacroBenchmark können Sie den Kompilierungsmodus direkt angeben.

Systemüberlegungen

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.

Alt-Text 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:

Alt-Text 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:

Alt-Text 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?

Alt-Text 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:

Alt-Text Abbildung 5: Eine Spur, die einen ruckeligen Frame zeigt.

Sie können üben, sie zu identifizieren.

Alt-Text 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:

  • Kaltstart: Hiermit wird ein neuer Prozess ohne gespeicherten Status erstellt.
  • 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.

Wir empfehlen, Systraces mit der System Tracing App auf dem Gerät zu erfassen. Verwenden Sie für Android 10 und höher Perfetto. Verwenden Sie für Android 9 und niedriger Systrace. Wir empfehlen außerdem, die Ablaufverfolgungsdateien mit der webbasierten Perfetto Trace Viewer. Weitere Informationen finden Sie unter Systemübersicht Tracing

Achten Sie unter anderem auf Folgendes:

  • 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:

  1. 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.

    Alt-Text Abbildung 7: Objektanzahl wird erhöht.

    Alt-Text 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.

  2. 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.

    Alt-Text 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.

      Alt-Text Abbildung 10: Vollständiger Arbeitsspeicher-Dump.

      <ph type="x-smartling-placeholder">
      </ph> Spalte &quot;Beibehaltene Größe&quot;.
      Abbildung 11. Spalte „Größe beibehalten“.
  3. Messen Sie die Auswirkungen einer Optimierung.

    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.