Lo strong skipping è una modalità disponibile nel compilatore Compose. Se abilitata, modifica il comportamento del compilatore in due modi:
- Gli elementi componibili con parametri instabili diventano ignorabili
- Viene effettuata la memorizzazione delle funzioni lambda con acquisizioni instabili
Attiva la modalità di skipping avanzato
La modalità di skipping avanzata è abilitata per impostazione predefinita in Kotlin 2.0.20.
Per attivare lo strong skipping per un modulo Gradle in una release precedente alla 2.0.20,
includi la seguente opzione nel
blocco composeCompiler della configurazione Gradle:
android { ... }
composeCompiler {
enableStrongSkippingMode = true
}
Possibilità di ignorare componibile
La modalità di skipping avanzato allenta alcune delle regole di stabilità normalmente applicate dal compilatore Compose per quanto riguarda lo skipping e le funzioni componibili. Per impostazione predefinita, il compilatore Compose contrassegna una funzione componibile come ignorabile se tutti i suoi argomenti hanno valori stabili. La modalità di strong skipping cambia questa situazione.
Con lo strong skipping abilitato, tutte le funzioni componibili riavviabili diventano ignorabili. Questo vale indipendentemente dal fatto che abbiano o meno parametri instabili. Le funzioni componibili non riavviabili rimangono non ignorabili.
Quando saltare
Per determinare se saltare un componibile durante la ricomposizione, Compose confronta il valore di ogni parametro con i valori precedenti. Il tipo di confronto dipende dalla stabilità del parametro.
- I parametri instabili vengono confrontati utilizzando l'uguaglianza delle istanze (
===) - I parametri stabili vengono confrontati utilizzando l'uguaglianza degli oggetti (
Object.equals())
Se tutti i parametri soddisfano questi requisiti, Compose salta il componibile durante la ricomposizione.
Potresti voler disattivare lo strong skipping per un componibile. In altre parole, potresti volere un composable riavviabile, ma non ignorabile. In questo caso, utilizza l'annotazione @NonSkippableComposable.
@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}
Annota le classi come stabili
Se vuoi che un oggetto venga confrontato utilizzando l'uguaglianza degli oggetti (Object.equals()) anziché l'uguaglianza delle istanze (===), continua ad annotare la classe specificata con @Stable o @Immutable.
Prima di aggiungere @Stable o @Immutable, tieni presente i seguenti compromessi:
- Le classi con proprietà stabili nei moduli Compose sono già stabili: una classe con
valproprietà di tipi stabili in un modulo compilato con il compilatore Compose viene dedotta automaticamente come stabile e utilizza.equals()senza bisogno di@Immutableo@Stable. - Annota solo le classi con controlli
.equals()economici: aggiungi@Stableo@Immutablequando il compilatore non può dedurre la stabilità (ad esempio le classi dei moduli non Compose) e vengono allocate spesso nuove istanze con valori identici, a condizione che il controllo.equals()della classe sia economico. - Fai attenzione quando annoti i modelli con le raccolte: l'aggiunta di
@Stableo@Immutableai modelli contenenti raccolte (o la sostituzione diListconImmutableList) fa sì che Compose confronti ogni elemento della raccolta con.equals()in ogni passaggio di ricomposizione. Per raccolte o modelli di grandi dimensioni utilizzati in layout lazy (LazyColumn,LazyRow,LazyGrid), il confronto di ogni elemento può essere più lento rispetto all'utilizzo dell'uguaglianza delle istanze (===) o alla ricomposizione diretta.
Memoizzazione Lambda
La modalità di strong skipping consente anche una maggiore memorizzazione delle espressioni lambda all'interno dei componibili. Con lo strong skipping abilitato, ogni lambda all'interno di una funzione componibile verrà memorizzata automaticamente.
Esempi
Per ottenere la memorizzazione delle espressioni lambda all'interno dei componibili quando utilizzi lo skipping forte, il compilatore racchiude l'espressione lambda in una chiamata remember. È associato alle acquisizioni della lambda.
Considera un caso in cui hai una funzione lambda come nell'esempio seguente:
@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
val lambda = {
use(unstableObject)
use(stableObject)
}
}
Con lo strong skipping abilitato, il compilatore memorizza la funzione lambda inserendola in una chiamata remember:
@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
val lambda = remember(unstableObject, stableObject) {
{
use(unstableObject)
use(stableObject)
}
}
}
Le chiavi seguono le stesse regole di confronto delle funzioni componibili. Il runtime confronta le chiavi instabili utilizzando l'uguaglianza delle istanze. Confronta le chiavi stabili utilizzando l'uguaglianza degli oggetti.
Memoizzazione e ricomposizione
Questa ottimizzazione aumenta notevolmente il numero di componibili che il runtime salta durante la ricomposizione. Senza la memorizzazione, è molto più probabile che il runtime assegni una nuova lambda a qualsiasi componibile che accetta un parametro lambda durante la ricomposizione. Di conseguenza, la nuova funzione lambda ha parametri che non sono uguali a quelli dell'ultima composizione. Questo comporta la ricomposizione.
Evita la memorizzazione
Se hai una funzione lambda che non vuoi memorizzare, utilizza l'annotazione @DontMemoize.
val lambda = @DontMemoize {
...
}
Dimensioni APK
Durante la compilazione, i composabili ignorabili generano più codice rispetto ai composabili non ignorabili. Con la modalità di salto avanzata attiva, il compilatore contrassegna quasi tutti i componibili come ignorabili e inserisce tutte le espressioni lambda in un remember{...}. Per questo motivo, l'attivazione della modalità di salto avanzata ha un impatto molto ridotto sulle dimensioni dell'APK della tua applicazione.
L'attivazione dello skipping avanzato in Now In Android ha aumentato le dimensioni dell'APK di 4 kB. La differenza di dimensioni dipende in gran parte dal numero di composabili precedentemente non ignorabili presenti nell'app, ma dovrebbe essere relativamente ridotta.