O Compose considera os tipos como estáveis ou instáveis. Um tipo é estável se é imutável, ou se é possível para o Compose saber se o valor tem mudou entre as recomposições. Um tipo é instável quando o Compose não consegue saber se seu valor mudou entre as recomposições.
O Compose usa a estabilidade dos parâmetros de um elemento combinável para determinar se ele pode pular o elemento combinável durante a recomposição:
- Parâmetros estáveis:se um elemento combinável tem parâmetros estáveis que não foram for alterado, o Compose a ignorará.
- Parâmetros instáveis:se um elemento combinável tiver parâmetros instáveis, o Compose sempre o recompõe ao recompor o pai do componente.
Se o app inclui muitos componentes desnecessariamente instáveis que o Compose sempre usa durante a recomposição, poderá observar problemas de desempenho e outros problemas.
Este documento detalha como aumentar a estabilidade do seu app para melhorar desempenho e experiência geral do usuário.
Objetos imutáveis
Os snippets a seguir demonstram os princípios gerais por trás da estabilidade e recomposição.
A classe Contact
é de dados imutável. Isso porque todos os seus
parâmetros são primitivos definidos com a palavra-chave val
. Depois de criar um
instância de Contact
, não será possível alterar o valor das propriedades do objeto.
Se você tentasse fazer isso, criaria um novo objeto.
data class Contact(val name: String, val number: String)
O elemento combinável ContactRow
tem um parâmetro do tipo Contact
.
@Composable
fun ContactRow(contact: Contact, modifier: Modifier = Modifier) {
var selected by remember { mutableStateOf(false) }
Row(modifier) {
ContactDetails(contact)
ToggleButton(selected, onToggled = { selected = !selected })
}
}
Considere o que acontece quando o usuário clica no botão ativar e o
selected
mudança de estado:
- O Compose avalia se precisa recompor o código dentro de
ContactRow
. - Ele percebe que o único argumento para
ContactDetails
é do tipoContact
. - Como
Contact
é uma classe de dados imutável, o Compose garante que nenhuma os argumentos deContactDetails
mudaram. - Dessa forma, o Compose ignora a
ContactDetails
e não a recompõe. - Por outro lado, os argumentos de
ToggleButton
mudaram. O Compose faz a recomposição desse componente.
Objetos mutáveis
Embora o exemplo anterior use um objeto imutável, é possível criar um um objeto mutável. Confira o snippet a seguir:
data class Contact(var name: String, var number: String)
Como cada parâmetro de Contact
agora é um var
, a classe não é mais imutável.
Se as propriedades fossem alteradas, o Compose não ficaria ciente disso. Isso ocorre porque
O Compose só monitora mudanças em objetos de estado do Compose.
O Compose considera essa classe instável. O Compose não ignora a recomposição de
classes instáveis. Dessa forma, se Contact
for definido dessa maneira, ContactRow
no exemplo anterior, seria recomposta sempre que selected
mudasse.
Implementação no Compose
Pode ser útil, embora não seja crucial, considerar exatamente como o Compose determina quais funções pular durante a recomposição.
Quando o compilador do Compose é executado no seu código, ele marca cada função e tipo. com uma das várias tags. Essas tags refletem como o Compose processa a função ou durante a recomposição.
Funções
O Compose pode marcar funções como skippable
ou restartable
. Observe que pode
marcar uma função como um, ambos ou nenhum destes:
- Pulável: se o compilador marcar um elemento combinável como pulável, o Compose poderá ignorá-la durante a recomposição se todos os seus argumentos forem iguais à própria valores anteriores.
- Reinicializável: um elemento combinável que pode ser reiniciado serve como um "escopo". em que a recomposição pode começar. Em outras palavras, a função pode ser um ponto de entrada de onde o Compose pode começar a executar novamente o código para recomposição após as mudanças de estado.
Tipos
O Compose marca os tipos como imutáveis ou estáveis. Cada tipo é um ou o outro:
- Imutável: o Compose marca um tipo como imutável se o valor dele
propriedades nunca podem mudar e todos os métodos são referenciais transparentes.
- Todos os tipos primitivos são marcados como imutáveis. Isso inclui
String
,Int
eFloat
.
- Todos os tipos primitivos são marcados como imutáveis. Isso inclui
- Estável: indica um tipo com propriedades que podem ser alteradas após a construção. Se e quando essas propriedades mudarem durante o tempo de execução, o Compose vai reconhecer essas mudanças.
Depurar estabilidade
Se o app estiver recompondo um elemento combinável que não teve parâmetros alterados, primeiro
verifique a definição de parâmetros que são claramente mutáveis. Escrever sempre
recompõe um componente quando você transmite um tipo com as propriedades var
ou um val
que usam um tipo instável conhecido.
Para informações detalhadas sobre como diagnosticar problemas complexos com estabilidade em Compose, consulte o guia Depurar estabilidade.
Corrigir problemas de estabilidade
Para saber mais sobre como oferecer estabilidade na implementação do Compose, consulte o guia Corrigir problemas de estabilidade.
Resumo
Em geral, você deve observar os seguintes pontos:
- Parâmetros: o Compose determina a estabilidade de cada parâmetro do elementos combináveis para determinar quais elementos devem ser ignorados durante recomposição.
- Correções imediatas: se você notar que o elemento combinável não está sendo ignorado e
ela está causando um problema de desempenho, verifique as causas óbvias
instabilidade como parâmetros
var
primeiro. - Relatórios do compilador: você pode usar os relatórios do compilador para determinar a estabilidade das classes.
- Coleções: o Compose sempre considera as classes de coleção instáveis, como
como
List, Set
eMap
. Isso ocorre porque não é possível garantir que eles são imutáveis. Use as coleções imutáveis do Kotlinx ou anotar suas classes como@Immutable
ou@Stable
; - Outros módulos: o Compose sempre considera instável a origem deles. módulos em que o compilador do Compose não é executado. Unir as classes na interface classes de modelo, se necessário.
Leia mais
- Desempenho: para mais dicas de depuração sobre o desempenho do Compose, consulte no nosso guia de práticas recomendadas e na palestra do Google I/O.