Comment collecter des analyses et ne pas tuer la productivité

Analytics fait partie intégrante d'une application mobile moderne. Analytics vous permet de collecter des informations sur l'utilisateur afin de développer et d'améliorer le produit.

Souvent, la collecte d'informations réduit les performances des applications. Le processus charge en outre le CPU et la mémoire, et c'est un prix élevé. Un fonctionnement lent de l'application peut entraîner des avis négatifs des utilisateurs, abaisser la note et entraîner une perte d'audience.

Notre équipe de développeurs Android a rencontré ce problème lors du travail sur le prochain projet, qui était lié à l'actualité. Nous avons dû enregistrer l'affichage de chaque nouvelle dans la liste.

Tentative numéro 1


Ayant reçu la tâche de collecter des analyses, l'équipe a rapidement montré le résultat. Le déclencheur pour générer un événement était la méthode onViewAttachedToWindow . Tout semble bien se passer, mais avec un défilement rapide, l'interface s'est sensiblement bloquée - quelque chose s'est mal passé. Le problème devait être résolu.

Tout le monde perçoit la suspension différemment, nous avions donc besoin de faits et de preuves. Pour mesurer le décalage, FPS (Frames Per Second) a été choisi, et FPS-mètre TinyDenser pour mesurer le décalage . Après avoir connecté l'utilitaire, l'équipe a reçu une confirmation objective du problème - l'indicateur est tombé, parfois de manière assez notable: moins de 30 images par seconde, l'enregistrement d'écran avec l'utilitaire activé est illustré à la figure 1.

image
Figure 1. Enregistrement d'écran avant optimisation

Tentative numéro 2


Et si vous retardez l'envoi d'événements jusqu'à ce que l'utilisateur fasse défiler la liste? Hmmm, l'équipe réfléchit et décida de créer une file d'attente d'événements et de les envoyer après l'arrêt du défilement. Tout est simple ici: nous ajoutons OnScrollListener à RecyclerView et attendons que le newState soit à plat SCROLL_STATE_IDLE - le problème est partiellement résolu.

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

L'étape suivante consiste à mettre en œuvre l'accumulation d'événements et leur diffusion.

Pour gérer la file d'attente, nous avons créé une classe chargée d'ajouter des événements à la file d'attente et d'envoyer des analyses au service. Pour l'envoi périodique, nous avons choisi un ScheduledExecutorService avec un thread qui exécutait Runnable toutes les secondes, l'heure a été sélectionnée empiriquement.

Cela a immédiatement donné des résultats, une augmentation significative du FPS. En principe, le problème a été résolu, sur la figure 2, nous voyons le résultat de l'application après la deuxième tentative. Mais il n'y avait qu'une seule tâche - des événements ont été envoyés au service, ce qui a conduit à la génération fréquente d'objets de la classe Intent , ce qui a en outre surchargé le GC et livré des «choses agréables» sous la forme de pauses d' arrêt du monde .

image
Figure 2. Enregistrement d'écran après la deuxième tentative

Tentative numéro 3


«L'envoi non d'un événement à la fois, mais d'une liste d'événements est une autre merveilleuse idée», a pensé l'équipe. Après un bref raffinement de la classe, l'équipe a implémenté la répartition des événements par la liste et a reçu des valeurs stables de l'indicateur au niveau de 55 à 60 images par seconde (figure 3).

image

Figure 3. Enregistrement d'écran après la troisième tentative

Conclusions


La tâche triviale de collecte d'analyses s'est transformée en un processus intéressant et informatif, au cours duquel l'équipe a mis à profit ses compétences pour rechercher des problèmes de performances des applications et trouver des moyens de les résoudre. J'espère que notre expérience sera utile aux débutants comme aux développeurs expérimentés.

Pourrait-on faire autre chose?


Notre équipe a opté pour la troisième option, mais ce n'est pas la seule chose qui pourrait être appliquée.

Dans l'implémentation actuelle, lorsque la méthode onViewAttachedToWindow est déclenchée, les actualités sont transformées en un objet d'événement analytique et, par conséquent, un nouvel objet est créé. Une des solutions possibles est de reporter la conversion jusqu'au moment de l'envoi: accumuler dans la file d'attente non pas les événements, mais les éléments de la liste eux-mêmes. Ensuite, la conversion se produit lorsque le défilement est en mode SCROLL_STATE_IDLE . Vous pouvez également créer un pool d'objets pour les événements. Ensemble, ces actions peuvent donner une augmentation supplémentaire des performances des applications.

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


All Articles