Wie man Analysen sammelt und nicht die Produktivität beeinträchtigt

Analytics ist ein wesentlicher Bestandteil einer modernen mobilen Anwendung. Mit Analytics können Sie Informationen über den Benutzer sammeln, um das Produkt zu entwickeln und zu verbessern.

Das Sammeln von Informationen verringert häufig die Anwendungsleistung. Der Prozess lädt zusätzlich die CPU und den Speicher, und dies ist ein hoher Preis. Ein langsamer Betrieb der Anwendung kann zu negativen Bewertungen der Benutzer führen, die Bewertung verringern und zum Verlust des Publikums führen.

Unser Team von Android-Entwicklern hatte dieses Problem bei der Arbeit am nächsten Projekt, das mit den Nachrichten zu tun hatte. Wir mussten die Anzeige jeder Nachricht in der Liste registrieren.

Versuch Nummer 1


Nachdem das Team die Aufgabe erhalten hatte, Analysen zu sammeln, zeigte es schnell das Ergebnis. Der Auslöser für die Generierung eines Ereignisses war die onViewAttachedToWindow- Methode. Alles scheint in Ordnung zu sein, aber mit einem schnellen Bildlauf blieb die Benutzeroberfläche spürbar hängen - etwas ging schief. Das Problem musste gelöst werden.

Jeder nimmt die Aussetzung anders wahr, deshalb brauchten wir Fakten und Beweise. Zur Messung der Verzögerung wurde FPS (Frames Per Second) und FPS-Meter TinyDenser zur Messung der Verzögerung ausgewählt . Nach dem Anschließen des Dienstprogramms erhielt das Team eine objektive Bestätigung des Problems - die Anzeige fiel manchmal merklich ab: Bei weniger als 30 Bildern pro Sekunde ist die Bildschirmaufzeichnung bei eingeschaltetem Dienstprogramm in Abbildung 1 dargestellt.

Bild
Abbildung 1. Bildschirmaufnahme vor der Optimierung

Versuch Nummer 2


Und wenn Sie das Senden von Ereignissen verschieben, bis der Benutzer die Liste scrollt? Hmmm, dachte das Team und beschloss, eine Warteschlange mit Ereignissen zu erstellen und diese zu senden, nachdem der Bildlauf gestoppt wurde. Hier ist alles einfach: Fügen Sie OnScrollListener zur RecyclerView hinzu und warten Sie, bis newState flach ist. SCROLL_STATE_IDLE - das Problem ist teilweise gelöst.

class IdleStateScrollListener(private val analyticsFacade: AnalyticsFacade) : RecyclerView.OnScrollListener() { fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { analyticsFacade.setPending(newState != RecyclerView.SCROLL_STATE_IDLE) } } 

Der nächste Schritt besteht darin, die Anhäufung von Ereignissen und deren Versand zu implementieren.

Um die Warteschlange zu verwalten, haben wir eine Klasse erstellt, die für das Hinzufügen von Ereignissen zur Warteschlange und das Senden von Analysen an den Dienst verantwortlich war. Für das regelmäßige Senden haben wir einen ScheduledExecutorService mit einem Thread ausgewählt, auf dem Runnable jede Sekunde ausgeführt wird. Die Zeit wurde empirisch ausgewählt.

Dies führte sofort zu Ergebnissen, einem signifikanten Anstieg der FPS. Im Prinzip wurde das Problem gelöst, in Abbildung 2 sehen wir das Ergebnis der Anwendung nach dem zweiten Versuch. Es gab jedoch nur eine Aufgabe: Ereignisse wurden an den Dienst gesendet, was zur häufigen Erzeugung von Objekten der Intent- Klasse führte. Dies belastete den GC zusätzlich und lieferte „angenehme Dinge“ in Form von Stop-the-World- Pausen.

Bild
Abbildung 2. Bildschirmaufnahme nach dem zweiten Versuch

Versuch Nummer 3


„Es ist eine weitere wunderbare Idee, nicht jeweils eine Veranstaltung, sondern eine Liste von Veranstaltungen zu senden“, dachte das Team. Nach einer kurzen Verfeinerung der Klasse implementierte das Team den Versand von Ereignissen anhand der Liste und erhielt stabile Werte des Indikators auf der Ebene von 55 bis 60 Bildern pro Sekunde (Abbildung 3).

Bild

Abbildung 3. Bildschirmaufnahme nach dem dritten Versuch

Schlussfolgerungen


Die triviale Aufgabe, Analysen zu sammeln, wurde zu einem interessanten und informativen Prozess, in dem das Team seine Fähigkeiten in die Erforschung von Anwendungsleistungsproblemen und die Suche nach Lösungsmöglichkeiten einbrachte. Ich hoffe, unsere Erfahrung ist sowohl für Anfänger als auch für erfahrene Entwickler nützlich.

Könnte noch etwas getan werden?


Unser Team hat sich für die dritte Option entschieden, aber dies ist nicht das einzige, was angewendet werden kann.

In der aktuellen Implementierung werden beim Auslösen der Methode onViewAttachedToWindow die Nachrichten in ein Analyseereignisobjekt umgewandelt und entsprechend ein neues Objekt erstellt. Eine der möglichen Lösungen besteht darin, die Konvertierung auf den Zeitpunkt des Sendens zu verschieben: Nicht die Ereignisse, sondern die Listenelemente selbst in der Warteschlange zu sammeln. Die Konvertierung erfolgt dann, wenn sich der Bildlauf im SCROLL_STATE_IDLE- Modus befindet. Sie können auch einen Objektpool für Ereignisse erstellen. Zusammen können diese Aktionen die Anwendungsleistung zusätzlich steigern.

Source: https://habr.com/ru/post/de414899/


All Articles