Modo forte para pular

A ação "pular" forte é um modo disponível no compilador do Compose. Quando ativada, ela muda o comportamento do compilador de duas maneiras:

  • Os elementos combináveis com parâmetros instáveis se tornam puláveis.
  • Os lambdas com capturas instáveis são lembrados

Ativar o modo de rejeição avançada

Para ativar o recurso "pular" de forma forte em um módulo do Gradle, inclua a seguinte opção no bloco composeCompiler da configuração do Gradle:

composeCompiler {
   enableStrongSkipping = true
}

Possibilidade de pular da composição

O modo de pular forte relaxa algumas das regras de estabilidade normalmente aplicadas pelo compilador do Compose quando se trata de pular e funções combináveis. Por padrão, o compilador do Compose marcará uma função combinável como pulável se todos os argumentos tiverem valores estáveis. O modo "pular" forte muda isso.

Com a opção de pular forte, todas as funções combináveis reinicializáveis se tornam puláveis. Isso se aplica independentemente de terem parâmetros instáveis. As funções combináveis não reiniciáveis permanecem não puláveis.

Quando pular

Para determinar se um elemento combinável precisa ser ignorado durante a recomposição, o Compose compara o valor de cada parâmetro com os valores anteriores. O tipo de comparação depende da estabilidade do parâmetro.

  • Parâmetros instáveis são comparados usando a igualdade de instância (===)
  • Parâmetros estáveis são comparados usando a igualdade de objeto (Object.equals())

Se todos os parâmetros atenderem a esses requisitos, o Compose vai ignorar o elemento combinável durante a recomposição.

É recomendável que um elemento combinável desative o recurso de pulo forte. Ou seja, talvez você queira um elemento combinável que pode ser reiniciado, mas não pulável. Nesse caso, use a anotação @NonSkippableComposable.

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

Anotar classes como estáveis

Se você quiser um objeto usando a igualdade de objeto em vez da igualdade de instância, continue a anotar a classe especificada com @Stable. Um exemplo de quando você pode precisar fazer isso é ao observar uma lista inteira de objetos, as fontes de dados, como o Room, vão alocar novos objetos para cada item na lista sempre que um deles mudar.

Memória lambda

O modo forte para pular também permite mais memoização de lambdas dentro de elementos combináveis. Com o recurso de pular forte ativado, cada lambda dentro de uma função combinável será lembrado automaticamente.

Exemplos

Para conseguir a memoização de lambdas dentro de elementos combináveis usando o pulo forte, o compilador encapsula a lambda com uma chamada remember. Ela é codificada com as capturas da lambda.

Considere um caso em que há um lambda, como no exemplo abaixo:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

Com a opção "pular" forte ativada, o compilador memoriza a lambda unindo-a em uma chamada remember:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

As chaves seguem as mesmas regras de comparação que as funções combináveis. O ambiente de execução compara chaves instáveis usando a igualdade de instância. Ele compara chaves estáveis usando a igualdade de objeto.

Memoização e recomposição

Essa otimização aumenta muito o número de elementos combináveis que o ambiente de execução ignora durante a recomposição. Sem a memorização, é muito mais provável que o ambiente de execução aloque um novo lambda a qualquer elemento combinável que use um parâmetro lambda durante a recomposição. Como resultado, a nova lambda tem parâmetros que não são iguais à última composição. Isso resulta na recomposição.

Evitar memorização

Se você tiver uma lambda que não quer memorizar, use a anotação @DontMemoize.

val lambda = @DontMemoize {
    ...
}

Tamanho do APK

Quando compilados, os elementos combináveis puláveis resultam em mais código gerado do que os que não são puláveis. Com o recurso de pular forte ativado, o compilador marca quase todos os elementos combináveis como puláveis e encapsula todos os lambdas em um remember{...}. Por isso, ativar o modo forte para ignorar tem um impacto muito pequeno no tamanho do APK do seu aplicativo.

A ativação do recurso "pular" forte no Now in Android aumentou o tamanho do APK em 4 KB. A diferença de tamanho depende em grande parte do número de elementos combináveis anteriormente não puláveis que estavam presentes no app especificado, mas precisam ser relativamente menores.