Technologies Natives

Jetpack Compose: toute classe d’un autre module est-elle instable ?

Récemment, j'ai assisté à Mobilis in Mobile à Nantes, qui était centrée sur le développement mobile. Lors de la première conférence, Vincent Auguin a abordé les bonnes pratiques de développement avec Jetpack Compose. J'ai été particulièrement intéressé par une information qu'il a partagé : toute classe provenant d'un autre module est considérée comme instable. Cette information m'a surpris, car je n'avais pas remarqué de problème de performance dans mes propres applications développées avec Jetpack Compose.

Toute classe provenant d'un autre module est considérée comme instable

Si vous êtes débutants en compose, vous devez absolument voir cette conférence (un enregistrement vidéo a été fait, il sera disponible d’ici peu). Si la vidéo n’est toujours pas disponible au moment où vous lisez cet article, Ben Trengrove a expliqué a peu près les mêmes choses à l’Android Dev Summit de 2022.

Dans Jetpack Compose, la stabilité d'un paramètre détermine si un composant doit se rendre à nouveau ou non lorsque son parent est lui-même recomposé. Si une classe est considérée comme instable à tort, cela peut entraîner une diminution des performances d'affichage de l'application. Étant donné que de nombreuses applications sont maintenant construites avec une architecture multi-modules, il est courant d'utiliser des classes provenant d'autres modules dans un composant Jetpack Compose.

Pour vérifier si ce problème est toujours d'actualité avec les dernières versions de Compose (1.4.3) et du compose compiler (1.4.7), j'ai effectué un test en utilisant le Layout Inspector d'Android Studio, qui permet d'afficher les recompositions de chaque composable.

Voici un exemple de code que j'ai utilisé pour le test :


Pour forcer la recomposition, il suffit d'avoir une action qui modifie le contenu du composable. Si le paramètre de ++code>ComposableUsingModel++/code> était stable, il ne se recomposerait pas.


J'ai donc ajouté un composable avec un paramètre correspondant à une ++code>data class++/code> considérée comme stable pour une utilisation intra-module. J'ai placé ce composable dans un parent et forcé son rendu lors d'un clic. Malheureusement, les résultats du test ont confirmé que le problème persiste.

La colonne de gauche indique le nombre de recompositions, tandis que la colonne de droite affiche le nombre de recompositions évitées en raison de la stabilité des paramètres.


Comment éviter ce problème tout en gardant mon architecture multi-module ?

Maintenant que nous sommes conscients du problème de stabilité des classes provenant d'autres modules dans Jetpack Compose, il est temps de réfléchir à des solutions pour éviter ce problème tout en maintenant une architecture multi-module.

Pas question d'intégrer un framework UI dans mes couches métiers

Une solution possible aurait été d'annoter la classe en question avec ++code>@Stable++/code> et de faire tourner le compose compiler dans le module où ma classe modèle est stockée. Cependant, cela violerait mon architecture bien segmentée. Même si cela ne consiste qu'en une simple annotation, cela pourrait poser problème si je devais passer mon projet en Kotlin Multiplatform, ce qui ajouterait une contrainte supplémentaire. Il est donc préférable de trouver une autre solution.

Je renforce l'architecture en oignon de mon application Android

Chaque couche de  mon architecture actuelle (réseau, base de données, métier) manipule des objets spécifiques à cette couche. L’UI utilise pour l’instant les objets de ma couche métier. En donnant à ma couche UI des objets qui ne sont manipulés que dans cette couche, je peux mieux segmenter mon application. La solution que je propose est donc de convertir mes objets métier en objets UI au moment de les transmettre à mon composable. Bien sûr, mon composable et le type de son paramètre doivent être définis dans le même module.

Il existe deux solutions possibles pour cela :

Solution 1 : Copier la classe modèle

Solution 2 : Envelopper l'objet modèle dans une classe stable

En utilisant l'une de ces solutions, je peux transmettre des objets spécifiques à l'UI à mon composable, sans compromettre la stabilité des paramètres.

Conclusion

Il est essentiel de prendre en compte la stabilité des paramètres des composants Jetpack Compose pour éviter des recompositions indésirables. Cela s'applique notamment aux classes provenant d'autres modules, qui sont considérées comme instables par défaut, ce sera le cas pour LocalDateTime par exemple. En suivant une approche de renforcement de l'architecture en oignon et en convertissant les objets métier en objets UI au moment opportun, il est possible de contourner ce problème tout en maintenant une architecture multi-module solide. Toutefois, le compilateur compose est très performant, même si un composable est recomposé, ses sous-éléments ne seront pas recomposés dans le cas leurs paramètres sont stables, ce qui explique le fait de ne pas avoir remarqué le problème dans mon application: il est présent mais l’impact est mineur (dans mon cas).

Ressources

Le site web de Mobilis in mobile
La video Android Dev Summit 2022 sur les performances en compose

Développeur mobile ?

Rejoins nos équipes