Compose considère les types comme stables ou instables. Un type est stable s'il est immuable ou s'il est possible pour Compose de savoir si sa valeur a changé entre les recompositions. Un type est instable si Compose ne peut pas savoir si sa valeur a changé entre les recompositions.
Compose utilise la stabilité des paramètres d'un composable pour déterminer s'il peut l'ignorer lors de la recomposition:
- Stable parameters (Paramètres stables) : si un composable possède des paramètres stables qui n'ont pas changé, Compose l'ignore.
- Paramètres instables:si un composable possède des paramètres instables, Compose le recompose toujours lorsqu'il recompose le parent du composant.
Si votre application inclut de nombreux composants inutilement instables que Compose recompose toujours, vous risquez de rencontrer des problèmes de performances et d'autres problèmes.
Ce document explique comment améliorer la stabilité de votre application pour améliorer les performances et l'expérience utilisateur globale.
Objets immuables
Les extraits de code suivants illustrent les principes généraux sur lesquels reposent la stabilité et la recomposition.
La classe Contact
est une classe de données immuable. En effet, tous ses paramètres sont des primitives définies avec le mot clé val
. Une fois que vous avez créé une instance de Contact
, vous ne pouvez plus modifier la valeur des propriétés de l'objet.
Si vous tentez de le faire, vous devez créer un nouvel objet.
data class Contact(val name: String, val number: String)
Le composable ContactRow
comporte un paramètre de type Contact
.
@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
var selected by remember { mutableStateOf(false) }
Row(modifier) {
ContactDetails(contact)
ToggleButton(selected, onToggled = { selected = !selected })
}
}
Réfléchissez à ce qui se passe lorsque l'utilisateur clique sur le bouton d'activation et que l'état selected
change:
- Compose évalue s'il doit recomposer le code dans
ContactRow
. - Il constate que le seul argument pour
ContactDetails
est de typeContact
. Contact
étant une classe de données immuable, Compose s'assure qu'aucun des arguments deContactDetails
n'a changé.- Par conséquent, Compose ignore
ContactDetails
et ne la recompose pas. - D'autre part, les arguments de
ToggleButton
ont changé et Compose recompose ce composant.
Objets modifiables
Bien que l'exemple précédent utilise un objet immuable, il est possible de créer un objet modifiable. Prenons l'exemple de l'extrait suivant:
data class Contact(var name: String, var number: String)
Comme chaque paramètre de Contact
est désormais un var
, la classe n'est plus immuable.
Si ses propriétés étaient modifiées, Compose n'en serait pas informé. En effet, Compose ne suit que les modifications apportées aux objets State Compose.
Compose considère une telle classe comme instable. Compose n'ignore pas la recomposition des classes instables. Ainsi, si Contact
était défini de cette manière, ContactRow
dans l'exemple précédent se recomposerait chaque fois que selected
changeait.
Implémentation dans Compose
Il peut être utile, bien que ce ne soit pas crucial, de réfléchir à la façon dont Compose détermine précisément les fonctions à ignorer lors de la recomposition.
Lorsque le compilateur Compose s'exécute sur votre code, il marque chaque fonction et chaque type à l'aide de l'une des nombreuses balises. Ces balises reflètent la manière dont Compose gère la fonction ou le type lors de la recomposition.
Fonctions
Compose peut marquer des fonctions comme skippable
ou restartable
. Notez qu'il peut marquer une fonction comme l'un, les deux ou aucune de ces valeurs:
- Désactivable: si le compilateur marque un composable comme désactivable, Compose peut l'ignorer lors de la recomposition si tous ses arguments sont égaux à leurs valeurs précédentes.
- Redémarrable: un composable qui peut être redémarrable sert de "champ d'application" où la recomposition peut commencer. En d'autres termes, la fonction peut être un point d'entrée où Compose peut commencer à réexécuter du code pour la recomposition après un changement d'état.
Types
Compose marque les types comme immuables ou stables. Chaque type correspond à l'un ou à l'autre:
- Immutable: Compose marque un type comme immuable si la valeur de ses propriétés ne peut jamais changer et si toutes les méthodes sont transparentes sur le plan référentiel.
- Notez que tous les types primitifs sont marqués comme immuables. Il s'agit, par exemple, de
String
,Int
etFloat
.
- Notez que tous les types primitifs sont marqués comme immuables. Il s'agit, par exemple, de
- Stable: indique un type dont les propriétés peuvent être modifiées après la construction. Si ces propriétés changent au cours de l'exécution, Compose en est informé.
Stabilité au débogage
Si votre application recompose un composable dont les paramètres n'ont pas changé, vérifiez d'abord dans sa définition les paramètres clairement modifiables. Compose recompose toujours un composant si vous transmettez un type avec des propriétés var
ou une propriété val
qui utilise un type instable connu.
Pour en savoir plus sur le diagnostic des problèmes complexes de stabilité dans Compose, consultez le guide Déboguer la stabilité.
Résoudre les problèmes de stabilité
Pour savoir comment apporter de la stabilité à votre implémentation Compose, consultez le guide Résoudre les problèmes de stabilité.
Résumé
De manière générale, veuillez noter les points suivants:
- Paramètres: Compose détermine la stabilité de chaque paramètre de vos composables afin de déterminer les composables qu'il doit ignorer lors de la recomposition.
- Corrections immédiates: si vous remarquez que votre composable n'est pas ignoré et qu'il entraîne un problème de performances, vous devez d'abord vérifier les causes évidentes d'instabilité, comme les paramètres
var
. - Rapports du compilateur: vous pouvez utiliser les rapports de compilation pour déterminer la stabilité déduite de vos classes.
- Collections: Compose considère toujours les classes de collection comme étant instables, telles que
List, Set
etMap
. En effet, il ne peut pas être garanti qu'ils sont immuables. Vous pouvez utiliser les collections immuables Kotlinx à la place ou annoter vos classes en tant que@Immutable
ou@Stable
. - Autres modules: Compose considère toujours comme instable lorsqu'ils proviennent de modules dans lesquels le compilateur Compose ne s'exécute pas. Encapsulez les classes dans des classes de modèle d'UI, si nécessaire.
Complément d'informations
- Performances: pour obtenir d'autres conseils de débogage sur les performances de Compose, consultez notre guide des bonnes pratiques et notre présentation d'E/S.