Compose considera i tipi come stabili o instabili. Un tipo è stabile se è immutabile oppure se è possibile per Compose sapere se il suo valore è è cambiato tra una ricomposizione e l'altra. Un tipo è instabile se Compose non può sapere se il suo valore sia cambiato tra una ricomposizione e l'altra.
Compose utilizza la stabilità dei parametri di un componibile per determinare se puoi saltare l'operazione componibile durante la ricomposizione:
- Parametri stabili: se un componibile dispone di parametri stabili che non sono modificata, Compose la salta.
- Parametri instabili: se un componibile ha parametri instabili, Compose lo ricompone sempre quando ricompone l'elemento padre del componente.
Se la tua app include molti componenti inutilmente instabili che Compose sempre si ricompone, potresti riscontrare problemi di prestazioni e altri problemi.
Questo documento descrive come aumentare la stabilità della tua app per migliorare il rendimento e l'esperienza utente complessiva.
Oggetti immutabili
I seguenti snippet dimostrano i principi generali alla base di stabilità di ricomposizione.
La classe Contact
è una classe di dati immutabile. Questo perché tutte le sue
sono primitive definite con la parola chiave val
. Dopo aver creato
istanza di Contact
, non puoi modificare il valore delle proprietà dell'oggetto.
Se provi a farlo, devi creare un nuovo oggetto.
data class Contact(val name: String, val number: String)
Il componibile ContactRow
ha un parametro di 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 })
}
}
Pensa a cosa succede quando l'utente fa clic sul pulsante di attivazione/disattivazione e
selected
modifiche di stato:
- Compose valuta se deve ricomporre il codice all'interno di
ContactRow
. - Vede che l'unico argomento per
ContactDetails
è di tipoContact
. - Poiché
Contact
è una classe di dati immutabile, Compose è sicura che nessuno dei gli argomenti diContactDetails
sono cambiati. - Di conseguenza, Compose salta
ContactDetails
e non lo ricompone. - D'altra parte, gli argomenti per
ToggleButton
sono cambiati e Compose ricompone quel componente.
Oggetti mutevoli
Sebbene l'esempio precedente utilizzi un oggetto immutabile, è possibile creare un oggetto modificabile. Considera il seguente snippet:
data class Contact(var name: String, var number: String)
Poiché ogni parametro di Contact
è ora un var
, la classe non è più immutabile.
Se le proprietà cambiano, Compose non ne viene a conoscenza. Questo perché
Compose tiene traccia solo delle modifiche apportate agli oggetti di stato Compose.
Compose considera instabile questa classe. Compose non salta la ricomposizione dei
classi instabili. Di conseguenza, se Contact
fosse definito in questo modo, ContactRow
nell'esempio precedente si ricompone ogni volta che selected
viene modificato.
Implementazione in Compose
Può essere utile, anche se non fondamentale, valutare come esattamente Compose determina quali funzioni saltare durante la ricomposizione.
Quando il compilatore Compose viene eseguito sul codice, contrassegna ogni funzione e tipo con uno dei vari tag. Questi tag riflettono il modo in cui Compose gestisce la funzione o tipo durante la ricomposizione.
Funzioni
Scrivi può contrassegnare le funzioni come skippable
o restartable
. Tieni presente che potrebbe
contrassegna una funzione come una, entrambe o nessuna di queste:
- Ignorabile: se il compilatore contrassegna un componibile come ignorabile, Compose può ignoralo durante la ricomposizione se tutti i suoi argomenti sono uguali ai loro valori precedenti.
- Riavviabile: un componibile riavviabile funge da "ambito". dove la ricomposizione dei dati. In altre parole, la funzione può essere un punto voce in cui Compose può iniziare a rieseguire il codice per la ricomposizione dopo modifiche dello stato.
Tipi
Scrivi tipi di contrassegno come immutabili o stabili. Ogni tipo è uno altro:
- Immutabile: Compose contrassegna un tipo come immutabile se il suo valore
non possono mai cambiare e tutti i metodi sono referenzialmente trasparenti.
- Tieni presente che tutti i tipi primitivi sono contrassegnati come immutabili. Questi includono:
String
,Int
eFloat
.
- Tieni presente che tutti i tipi primitivi sono contrassegnati come immutabili. Questi includono:
- Stabile: indica un tipo le cui proprietà possono cambiare dopo la costruzione. Se e quando queste proprietà cambiano durante il runtime, Compose prende in considerazione tali modifiche.
Stabilità del debug
Se la tua app ricompone un componibile i cui parametri non sono stati modificati,
controlla la sua definizione di parametri che sono chiaramente mutabili. Scrivi sempre
ricompone un componente se passi in un tipo con proprietà var
, oppure un val
che usano un tipo instabile noto.
Per informazioni dettagliate su come diagnosticare problemi complessi con la stabilità Scrivi, consulta la guida Stabilità del debug.
Risolvere i problemi di stabilità
Per informazioni su come migliorare l'implementazione di Compose, vedi consulta la guida Risolvere i problemi di stabilità.
Riepilogo
Nel complesso, tieni presente quanto segue:
- Parametri: Compose determina la stabilità di ciascun parametro del tuo componibili per determinare quali componenti componibili saltare durante di ricomposizione.
- Correzioni immediate: se noti che il tuo componibile non viene ignorato e
perché è la causa di un problema di prestazioni, è necessario controllare le cause ovvie
instabilità come i parametri
var
. - Report del compilatore: puoi utilizzare i report del compilatore per: determinare quale stabilità delle tue classi viene dedotta.
- Raccolte: Compose considera sempre instabili le classi di raccolta, ad esempio
come
List, Set
eMap
. Questo perché non è possibile garantire che vengano sono immutabili. In alternativa, puoi utilizzare le raccolte immutabili di Kotlinx oppure annota i tuoi corsi come@Immutable
o@Stable
. - Altri moduli: Compose considera sempre instabili la loro provenienza moduli in cui non viene eseguito il compilatore Compose. Aggrega le classi nella UI le classi di modelli, se necessario.
Continua a leggere
- Rendimento: per altri suggerimenti di debug sulle prestazioni di Compose, consulta la nostra guida alle best practice e la nostra presentazione su I/O.