Usar o analisador de configuração do R8

O R8 Configuration Analyzer é uma ferramenta projetada para ajudar você a maximizar os benefícios de performance do R8, fornecendo insights detalhados sobre a qualidade da configuração do app. Ele permite rastrear e melhorar a otimização do R8 monitorando as principais métricas, especificamente as pontuações de redução, otimização e ofuscação, que indicam a porcentagem da base de código disponível para otimização. Ao identificar regras keep amplas ou desnecessárias, incluindo aquelas introduzidas por bibliotecas de terceiros, o analisador ajuda a refinar a configuração para garantir que o R8 possa otimizar o máximo possível de classes, campos e métodos.

Gerar o relatório

No AGP 9.3.0-alpha05 e mais recentes, o relatório é gerado automaticamente em build/outputs/mapping/release/configanalyzer.html ao executar um build do R8. Para desativar a geração automática das saídas, defina a seguinte propriedade do Gradle:

android.experimental.r8.enableR8ConfigurationAnalyzer=false

Para o AGP 9.2 e versões anteriores, defina a com.android.tools.r8.dumpkeepradiushtmltodirectory propriedade do sistema ao executar uma tarefa do Gradle com um build ativado com o R8.

./gradlew assembleRelease \
    -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=<output_directory>

Por exemplo, use o comando a seguir para gerar o relatório HTML no diretório /tmp/r8analysis:

// To create the /tmp/r8analysis folder.
mkdir -p /tmp/r8analysis

// To generate the report in the /tmp/r8analysis folder.
./gradlew assembleRelease \
    -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=/tmp/r8analysis

Entender o relatório

O R8 Configuration Analyzer fornece insights sobre a configuração do R8 do app e o impacto de cada regra keep no app. Isso ajuda você a alcançar a otimização máxima do R8, melhorando o desempenho do app. Use as pontuações a seguir para entender quanto da sua base de código está disponível para otimização pelo R8.

Exemplo da seção de resumo do relatório
Figura 1. Um exemplo da seção de resumo do relatório.

Pontuação de redução

Quando o R8 reduz o app, ele diminui o tamanho geral do app identificando e eliminando códigos e recursos não utilizados, garantindo que o build final seja o mais enxuto possível. A pontuação de redução acompanha a porcentagem de classes, campos e métodos sujeitos à redução. Por exemplo, uma pontuação de redução de 66% significa que o R8 pode realizar a redução em 66% da sua base de código.

Pontuação de otimização

O R8 realiza otimizações, como a incorporação de métodos e a mesclagem de classes, o que resulta em melhorias de inicialização e memória para o app. A pontuação de otimização acompanha a porcentagem de classes, campos e métodos sujeitos a otimizações do R8. Por exemplo, se a pontuação de otimização for de 66%, isso significa que o R8 só poderá realizar a otimização em 66% da sua base de código.

Pontuação de ofuscação

Ao ofuscar classes, campos e métodos em nomes mais curtos, o R8 reduz a pegada de metadados do app para economizar memória. A pontuação de ofuscação mede a porcentagem de código disponível para ofuscação na sua base de código.

Refinar regras keep

Para melhorar as pontuações e desbloquear uma melhor otimização do R8, refine as regras keep para que elas não impeçam desnecessariamente o R8 de otimizar o app. Mantenha apenas as classes, os métodos ou os campos acessados usando reflexão.

Para fazer isso, use a análise de regras keep.

Exemplo da análise de regra de permanência
Figura 2. Um exemplo da análise de regras keep.

Para conferir a análise detalhada de uma regra, clique nela para abrir a tela de detalhes.

Exemplo da análise de regra de permanência
Figura 3. Um exemplo da análise de regras keep.

Como refinar regras keep

Para refinar as regras keep e desbloquear todo o potencial das otimizações do R8 para seu app, faça o seguinte:

  1. Para cada regra keep, confira a porcentagem de classes, campos e métodos que não podem ser otimizados pelo R8 no Configuration Analyzer. Use isso para identificar as regras keep que impedem a otimização em um grande número de classes, campos ou métodos. As propriedades de otimização impedidas por cada regra keep também são listadas.
  2. Se você encontrar uma regra keep que esteja impedindo a otimização de um grande número de classes, verifique quais classes, campos e métodos estão impedidos de otimização pela regra keep para saber se essa regra está mantendo itens que não são invocados dinamicamente usando reflexão.
  3. Reduza a otimização bloqueada pelas regras keep segmentando apenas as classes, os campos ou os métodos necessários, escolhendo a opção keep certa e seguindo as práticas recomendadas.
  4. Investigue e execute testes que cubram as classes, os campos e os métodos afetados da regra keep e refine as regras keep.

Inspecionar a otimização de bibliotecas

Ao integrar bibliotecas de terceiros, elas geralmente incluem as próprias regras keep do consumidor para trabalhar com o R8. Como o autor da biblioteca não pode prever sua implementação específica, às vezes ele escreve regras conservadoras e abrangentes que impedem a otimização em mais classes, campos e métodos do que o necessário. Isso pode impedir que o R8 otimize partes do app que não têm nada a ver com a execução real da biblioteca. Você pode usar o R8 Configuration Analyzer para identificar bibliotecas que introduzem regras que afetam negativamente a otimização do app.

Use o Configuration Analyzer para inspecionar o efeito combinado de todas as regras keep do consumidor mescladas. Ao analisar o impacto de cada regra keep de uma biblioteca de terceiros, você pode identificar e rastrear as bibliotecas de terceiros específicas que impedem uma grande quantidade de otimização no app.

Como otimizar bibliotecas

  • Se uma biblioteca incluir uma regra muito ampla, recomendamos entrar em contato com o responsável pela manutenção da biblioteca com os dados do relatório para demonstrar como as regras atuais afetam as pontuações de otimização do app. Se for uma biblioteca externa, procure bugs existentes na biblioteca antes de registrar problemas.
  • Se necessário, você pode testar possíveis melhorias filtrando regras de uma biblioteca específica. É possível importar as regras da biblioteca para o projeto, excluir as amplas e executar novamente o Configuration Analyzer para medir os possíveis ganhos de tamanho e performance.

Regras subsumidas

Pode haver casos em que várias regras keep se sobrepõem e uma delas pode estar impedindo mais otimização do que o necessário. Se houver duas regras keep na sua base de código.

# Prevents optimization in the entire package
# Remove this to improve optimization
-keep class com.example.package.** { *; }

# Prevents optimization to the class inside the package
-keep class com.example.package.Myclass

A primeira regra keep, que impede a otimização em todo o pacote, está subsumindo a segunda regra keep, que tem como destino uma classe dentro do pacote mantido pela primeira regra keep. Quando as regras keep se sobrepõem, uma pode bloquear mais otimizações do que o necessário. Ao refinar essas regras sobrepostas, você pode maximizar a otimização do R8 e eliminar a dívida técnica. Esse processo envolve a simplificação da configuração para garantir que apenas o código essencial seja mantido, ao mesmo tempo em que desbloqueia todo o potencial dos recursos de otimização do R8.

Exemplo da seção de resumo do relatório
Figura 4. Um exemplo de regras subsumidas no relatório.

Otimizar regras subsumidas

  1. Encontre as regras keep subsumidas usando o R8 Configuration Analyzer.
  2. Identifique as classes, os campos ou os métodos exatos na sua base de código que realmente dependem da reflexão, que precisam ser mantidos usando regras keep. Saber disso vai ajudar você a refinar as regras keep.
  3. Usando o Configuration Analyzer, compare o impacto de cada regra que tem como destino as mesmas classes, campos ou métodos. Você pode usar a porcentagem de otimização impedida por cada regra keep para identificar qual é mais ampla e qual é uma regra keep estreita.
    1. Se a regra estreita for escrita com precisão, mantendo apenas os membros ou classes exatos que são acessados de forma reflexiva, remova a regra keep mais ampla. Isso desbloqueia com segurança as otimizações do R8 para o restante do pacote.
    2. Se a regra ampla tiver como destino as classes certas, mantenha a regra ampla e exclua a regra estreita. A regra estreita é apenas uma desordem redundante. Refine a regra ampla para segmentar apenas as classes, os campos ou os métodos que você identificou.

Verificar e testar as mudanças: execute novamente o Configuration Analyzer para garantir que o conflito seja corrigido. Em seguida, compile um build de lançamento e teste as mudanças para garantir que a base de código funcione conforme o esperado.

Remover regras desnecessárias

Usando o Configuration Analyzer, você pode auditar sistematicamente sua base de código para identificar e remover regras keep obsoletas que poluem sua configuração. O R8 Configuration Analyzer destaca especificamente duas fontes principais de regras desnecessárias:

  • Regras não utilizadas: regras que correspondem a zero classes, métodos ou campos no seu build atual. Elas geralmente persistem após a refatoração do código, a remoção de dependências ou de configurações de copiar e colar que não são mais relevantes, adicionando complexidade de configuração desnecessária.
  • Regras idênticas: regras keep idênticas significam regras que têm como destino as mesmas classes, campos e métodos ou declarações duplicadas de regras keep no mesmo arquivo de regras keep ou em arquivos diferentes.

Ambos os tipos de regras adicionam desordem à configuração, dificultando a manutenção e a depuração. Ao identificá-las, você pode limpar a configuração.