Desempenho do Jetpack Compose

O objetivo do Jetpack Compose é oferecer uma ótima performance por padrão. Esta página mostra como criar e configurar seu app para melhorar o desempenho e alguns padrões que precisam ser evitados.

Primeiro, conheça os principais conceitos do Compose em Como trabalhar com o Compose.

Configurar o app corretamente

Se o app estiver com baixo desempenho, talvez haja um problema de configuração. Uma boa etapa é verificar as opções de configuração a seguir.

Criar no modo de lançamento e usar o R8

Se você tiver problemas de desempenho, tente executar o app no modo de lançamento. O modo de depuração é útil para detectar muitos problemas, mas impõe um custo de desempenho significativo e pode dificultar a detecção de outros problemas de código que podem prejudicar a performance. Recomendamos também ativar a otimização e a redução com o compilador R8 para garantir um build de lançamento eficiente e eficiente.

Usar um perfil de referência

Os perfis de referência melhoram a velocidade de execução do código em 30% desde a primeira inicialização, evitando a interpretação e as etapas de compilação just-in-time (JIT) para caminhos de código incluídos. Ao enviar um perfil de referência em um app ou biblioteca, o Android Runtime (ART) pode otimizar os caminhos de código incluídos pela compilação antecipada (AOT, na sigla em inglês), fornecendo melhorias de desempenho a cada nova instalação de app e a cada atualização de app. Essa otimização guiada por perfil (PGO, na sigla em inglês) permite que os apps otimizem a inicialização, reduzam a instabilidade de interação e melhorem o desempenho geral de execução para usuários finais desde o primeiro lançamento.

O Compose é distribuído como uma biblioteca, em vez de fazer parte da plataforma Android. Essa abordagem permite que a equipe do Compose atualize o Compose com frequência e oferece suporte a versões mais antigas do Android. No entanto, a distribuição do Compose como uma biblioteca gera um custo. O código da plataforma Android já está compilado e instalado no dispositivo. No entanto, as bibliotecas precisam ser carregadas quando o app é iniciado e interpretado o JIT quando a funcionalidade é necessária. Isso pode deixar o app mais lento na inicialização e ao usar um recurso da biblioteca pela primeira vez.

Você pode melhorar a performance definindo perfis de referência. Esses perfis definem classes e métodos necessários em jornadas ideais do usuário e são distribuídos com o APK ou AAB do seu app. Durante a instalação do app, o ART compila esse código crítico AOT para que ele esteja pronto para uso quando o app for iniciado.

Nem sempre é simples definir um bom perfil de referência e, por isso, o Compose envia um por padrão. Talvez você não precise fazer nada para ter esse benefício. No entanto, o perfil de referência que acompanha o Compose contém apenas otimizações para o código na biblioteca do Compose. Para ter a melhor otimização, é recomendável também criar um perfil de referência para seu app que use a Macrobenchmark para cobrir jornadas ideais do usuário. Ao definir seu próprio perfil, você precisa testá-lo para verificar se ele está ajudando. Uma boa maneira de fazer isso é programar testes da Macrobenchmark para seu app e verificar os resultados do teste enquanto você cria e revisa seu perfil de referência. Para conferir um exemplo de como criar testes de Macrobenchmark para a interface do Compose, consulte o exemplo de Macrobenchmark do Compose (link em inglês).

Para conferir uma análise detalhada dos efeitos do modo de lançamento, do R8 e dos perfis de referência, consulte a postagem do blog Por que você sempre deve testar o desempenho do Compose na versão?.

Como as três fases do Compose afetam a performance

Conforme discutido em Fases do Jetpack Compose, quando o Compose atualiza um frame, ele passa por três fases:

  • Composição:o Compose determina o que mostrar. Ele executa funções combináveis e cria a árvore da interface.
  • Layout:o Compose determina o tamanho e o posicionamento de cada elemento na árvore da interface.
  • Exibição:o Compose renderiza os elementos da interface individuais.

O Compose pode ignorar essas fases de maneira inteligente se elas não forem necessárias. Por exemplo, suponha que um único elemento gráfico alterne entre dois ícones do mesmo tamanho. Como esse elemento não muda de tamanho e nenhum elemento da árvore da interface é adicionado ou removido, o Compose pode pular as fases de composição e layout e redesenhar esse único elemento.

No entanto, alguns erros de programação fazer com que seja difícil para o Compose saber quais fases ele pode ignorar com segurança. Em caso de dúvida, o Compose executa as três fases, o que pode deixar a interface mais lenta. Portanto, muitas das práticas recomendadas de desempenho servem para ajudar o Compose a pular as fases que ele não precisa fazer.

Há alguns princípios gerais a serem seguidos que podem melhorar a performance em geral:

  • Sempre que possível, remova os cálculos das funções combináveis. As funções combináveis podem precisar ser executadas novamente sempre que a interface mudar. Todo código colocado no elemento combinável é executado novamente, possivelmente para cada frame de uma animação. Limite o código do elemento combinável apenas ao necessário para criar a interface.

  • Adie as leituras de estado pelo maior tempo possível. Ao mover a leitura de estado para um elemento combinável ou uma fase posterior, você pode minimizar a recomposição ou pular completamente a fase de composição. É possível fazer isso transmitindo funções lambda em vez do valor do estado para mudar o estado com frequência e preferindo modificadores baseados em lambda ao transmitir estados com mudanças frequentes. Confira um exemplo dessa técnica na seção Adiar leituras pelo maior tempo possível.