Encontramos um método de otimização de desempenho da página inicial altamente compatível, de baixo custo e pronto para uso.

No início de 2020, a complexidade da interface do usuário da página inicial do Xiaohongshu aumentou significativamente. Ao otimizar o layout xml e usar alguns métodos stub, também procuramos alguns métodos de menor custo e melhor desempenho.

X2C era um método de otimização bem conhecido na indústria da época, cujo princípio era traduzir xml em código durante a compilação, o que pode efetivamente evitar a reflexão e a perda de leitura de arquivos de recursos. Como existem muitos cenários de visualização personalizados no APP Xiaohongshu, o X2C também trará altos custos de manutenção.

Após uma análise aprofundada e demorada do LayoutInflater, encontramos uma solução APT que é compatível com vários cenários de visualização. Esta solução evita as perdas causadas pela reflexão e não aumenta os custos adicionais de manutenção, tornando-a uma ferramenta que pode ser utilizada imediatamente.

Nossa exploração foi inspirada em ViewCompiler. Como uma ferramenta experimental do Google, o ViewCompiler pode converter manualmente layouts xml em arquivos java ou arquivos dex, mas não suporta mesclagem e inclusão de tags.

ViewCompiler foi introduzido no Android Q (Android 10), ainda é uma ferramenta experimental, então geralmente não temos como usá-lo. A imagem abaixo mostra o código-fonte do Android S (Android 12). Você pode ver que esse recurso não está ativado.

O princípio também é muito simples: primeiro gere um fragmento de código de modelo e, em seguida, gere o código lógico para percorrer o xml.

O principal benefício disso é que ele pode economizar o consumo de tempo causado pela reflexão. O AppCompatViewInflater oficial já cuidou da criação de Views nativas. Ao combinar diretamente o nome do novo objeto, evita a sobrecarga de desempenho causada pelo uso da reflexão.

No uso diário, a sobrecarga de desempenho de reflexão está concentrada principalmente na parte de visualização personalizada. Nosso aplicativo em si é uma cena com muitas visualizações personalizadas, por isso é naturalmente adequado para este método de VIewCompiler. Ao mesmo tempo, como todos os atributos serão percorridos ao percorrer o xml, isso também tem uma enorme vantagem em termos de manutenção. Não precisamos fazer nenhum processamento de atributos personalizados.

Com base na leitura do código-fonte e do código gerado do X2C e do ViewCompiler, decidimos fazer um que pudesse gerar código Kotlin e também resolver as tags de inclusão e mesclagem que o ViewCompiler não suporta. As ferramentas que usamos são relativamente convencionais, incluindo kapt e kotlinpoet. A ideia geral é obter o XmlResourceParser por meio de Resources.getLayout e, em seguida, percorrer as tags em cada xml através do next contínuo do analisador. O código gerado é o seguinte:

Ao encontrar mesclagem e inclusão, precisamos lidar especialmente com a lógica das chamadas recursivas para que o layout pai-filho possa ser conectado.

Depois de substituir algumas implementações de layout na página inicial por este novo método, descobrimos que o tempo de layout do p90 na página inicial online foi reduzido em mais de 200ms e indicadores como duração, CES e retenção foram significativamente melhorados.

O processo de trabalho do LayoutInflater

O processo de funcionamento do LayoutInflater pode ser simplesmente representado pela figura a seguir:

A solução descrita neste artigo é usar o apt para gerar código durante a compilação. Depois de analisar convenientemente o arquivo de layout, usamos o código gerado para criar diretamente uma instância. Sua eficiência é teoricamente consistente com a eficiência após atingir a lógica do componente básico do AppCompat.

Para componentes básicos do AppCompat, você pode visualizar o código-fonte AppCompatViewInflater.java (parcialmente mostrado acima), que inclui mais de uma dúzia de componentes básicos comumente usados, como TextView e Button.

No que diz respeito a um layout específico, o desempenho que pode ser melhorado através do uso do Layout2Code é apenas para outros componentes além dos componentes básicos, especialmente quando o layout utiliza um grande número de componentes customizados, o efeito é particularmente óbvio.

Isso também nos dá outro lembrete. Por exemplo, se você escrever TextView/TextViewCompat em xml, as instâncias eventualmente criadas sob a ação de AppCmpatViewInflater serão TextViewCompat. Mas quando não são utilizadas soluções do tipo Layout2Code ou X2C, sua eficiência é diferente: a primeira atinge a lógica de criação direta da figura acima, enquanto a segunda será criada por reflexão.

Desvantagens do X2C

Além das otimizações acima, o X2C também move a leitura e análise de arquivos de layout para o estágio de compilação para reduzir a sobrecarga de IO. Mas a maior dificuldade em analisar xml durante a compilação é que precisamos traduzir os atributos do View um por um. O motivo é que não há dependência do SDK durante a compilação, portanto é impossível gerar um objeto AtrributeSet para consumo direto por o construtor de View.

Como resultado, a manutenção manual das regras de tradução é necessária para converter atributos xml em código para definir atributos de visualização, o que traz vários problemas:

1. A quantidade de código gerado aumenta exponencialmente

2. Requer custos de manutenção extremamente altos para oferecer suporte a propriedades de visualização personalizadas

3. Alguns atributos xml não possuem métodos correspondentes ou não estão em correspondência um-para-um.

Em suma, é muito difícil manter uma funcionalidade robusta e completa nesta base. Comparada com a nova solução Layout2Code que estamos explorando, ela apresenta enormes vantagens em termos de compatibilidade e custos de manutenção. A única coisa que precisa ser ponderada é quanto espaço de otimização existe para leitura do arquivo de layout em tempo de execução e se vale a pena o investimento.

A particularidade dos arquivos de layout

Quando se trata de arquivos xml, você pensará reflexivamente em operações de IO com baixo desempenho. Isso é verdade, mas os arquivos de layout são muito especiais. Durante o processo de empacotamento do aplicativo Andorid, o AAPT empacotará os recursos e compactará os arquivos xml na pasta de ativos por meio da reutilização do pool de strings, conversão binária, etc. e, finalmente, gerará os arquivos de recursos compactados e os recursos de índice do arquivo de recursos .arsc. também arquivos R. Ao usar o AssetManager para carregar arquivos de recursos, também usaremos o mmap para reduzir os custos de IO.

Ao analisar os prós e os contras dos métodos acima, descobrimos que a leitura dos arquivos de layout geralmente não leva mais do que 1 ms após o teste em cenários reais de aplicativos. Portanto, considerando os custos de manutenção causados ​​pela passagem da leitura e análise dos arquivos de layout para a fase de compilação, optamos finalmente por abandonar diretamente esta parte da otimização.

No ambiente de desenvolvimento atual, a solução Layout2Code ainda pode desempenhar um grande papel na melhoria do desempenho.Claro, o pré-requisito para o uso eficaz desta solução é que os desenvolvedores compreendam totalmente o princípio da solução e seu escopo específico de aplicação (não AppComapt componentes) ).

Comparado com a solução X2C tradicional, o Layout2Code tem um escopo de aplicação mais amplo e custos de manutenção mais baixos. Atualmente, esta solução tem sido amplamente utilizada no APP Xiaohongshu e nos trouxe bons benefícios e efeitos. Nossa pesquisa sobre Layout2Code é implementada por kotlin e usando kapt. No futuro, também planejamos acessar ksp para reduzir o tempo de compilação e continuar a otimizar esta solução.

  Engenheiro Android de tecnologia empresarial Xiaohongshu

Aya Ren    Xiaohongshu Engenheiro Android de Tecnologia Empresarial

Acho que você gosta

Origin blog.csdn.net/REDtech_1024/article/details/130084859
Recomendado
Clasificación