Otimização do desempenho de renderização do Android - tudo o que você precisa saber!

Este artigo será dividido nas seguintes partes para analisar e resumir o desempenho de renderização: taxa de quadros e problemas de desempenho de renderização, causas de problemas de desempenho de renderização, métodos de otimização de desempenho de renderização, ferramentas de análise.

Taxa de quadros e problemas de desempenho de renderização


O artigo anterior "Princípios do mecanismo de renderização do Android (análise de todo o processo de princípios de exibição)" . No artigo, apresentei o mecanismo de renderização do Android e as causas dos problemas de desempenho, como gagueira. Aqui está uma breve revisão do que é a taxa de quadros e a gagueira.

Ao projetar o Android, a taxa de quadros é limitada a 60 quadros por segundo. Quando a taxa de quadros de nosso APP é 60fps, a imagem será muito suave. Mas, normalmente, devido a vários motivos, a taxa de quadros provavelmente será inferior a 60 fps, então haverá perda de quadros e o usuário se comportará como travamentos perceptíveis. Nossa taxa de quadros pode ser superior a 60 fps? A resposta é não. Isso ocorre porque a atualização e a renderização da interface dependem do sinal VSYNC da camada inferior. O sinal VSYNC é enviado para a camada superior a uma frequência de 60 vezes por segundo, e a taxa de quadros superior a 60fps também é desnecessária, porque a colaboração entre o olho humano e o cérebro não consegue perceber atualizações de imagem superiores a 60fps. (A taxa de atualização da tela da maioria dos telefones celulares é de 60 Hz, portanto, alta demais não faz sentido)

A meta de desempenho de desenvolver um aplicativo é manter 60fps, o que significa que você só tem 1000/60 = 16,67ms por quadro para processar todas as tarefas. Se não houver maneira de completar a tarefa deste quadro em 16 ms, ocorrerá perda de quadros. Quanto mais quadros forem eliminados, mais grave será a situação de congelamento que o usuário enfrentará.

Caton

A principal fonte de problemas de desempenho, como gagueira, que a maioria dos usuários percebe, é o desempenho de renderização, ou seja, não há como completar a tarefa desse quadro em 16ms, e ocorre perda de quadros. Do ponto de vista de designers e produtos, eles esperam que o aplicativo tenha mais elementos da moda, como animações e imagens, para proporcionar uma experiência de usuário tranquila. Mas o sistema Android pode não ser capaz de concluir essas operações complexas de renderização de interface a tempo. O sistema Android envia um sinal VSYNC a cada 16 ms para acionar a renderização da IU. Se cada renderização for bem-sucedida, ele pode atingir os 60 fps necessários para uma imagem suave. Para atingir 60 fps, isso significa que a maioria das operações do programa deve ser concluído em 16 ms.

Insira a descrição da imagem aqui

Se uma determinada operação do aplicativo demorar 24 ms, o sistema não será capaz de realizar a renderização normal quando o sinal VSYNC for recebido e ocorrerá perda de quadros. Então, o usuário verá o mesmo quadro em 32 ms.

Insira a descrição da imagem aqui

Quadro congelado

Já entendemos o congelamento, então o que é um quadro congelado?

Um quadro congelado é um quadro de interface cujo tempo de renderização excede 700 ms. Isso é um problema porque seu aplicativo fica travado por quase um segundo durante a apresentação do quadro e não responde à entrada do usuário. Normalmente recomendamos que o aplicativo renderize os quadros em 16 ms para garantir uma interface uniforme. No entanto, quando seu aplicativo é iniciado ou faz a transição para outra tela, o tempo de desenho do quadro inicial geralmente excede 16 ms, porque seu aplicativo deve expandir a visualização, organizar a tela e realizar o desenho inicial desde o início. Portanto, o Android controla os quadros congelados e a velocidade de renderização lenta separadamente. O tempo de renderização de qualquer quadro em seu aplicativo não deve exceder 700 ms.

Quadros congelados são uma forma extrema de renderização lenta, portanto, o processo de diagnóstico e solução do problema é o mesmo.

ANR

Comparado aos quadros congelados e congelados, o caso mais extremo é o ANR.

Se o thread de IU de um aplicativo Android for bloqueado por muito tempo, um erro de "aplicativo não está respondendo" (ANR) será acionado. Se o aplicativo estiver em primeiro plano, o sistema exibirá uma caixa de diálogo para o usuário e a caixa de diálogo ANR fornecerá ao usuário a opção de sair forçosamente do aplicativo.

Ao exibir ANR, o motivo usual é que o thread de IU é ocupado por outras tarefas (tarefas de não renderização, como operações de I / O, espera de bloqueio, etc.), e não há resposta à entrada do usuário e outras operações para um muito tempo. Problemas de ANR são desempenho muito sério Devemos tentar o nosso melhor para evitar problemas.

Como o ANR geralmente não é causado apenas por problemas de desempenho de renderização, não o explicaremos em detalhes aqui e escreveremos um capítulo separado para análise no futuro.

Causas de problemas de desempenho de renderização


Vamos pensar sobre as causas dos problemas de desempenho de renderização?

Existem muitos motivos que podem causar perda de quadros, congelamentos e outros problemas. Talvez seja porque seu layout é muito complicado para renderizar em 16 ms, pode ser porque você tem muitas unidades de desenho empilhadas em sua IU ou pode ser porque a animação é executada muitas vezes. Isso fará com que a CPU ou GPU fique sobrecarregada.

Aqui, eu resumo as seguintes razões principais:

  1. Overdraw
  2. Repita o layout
  3. Renderização repetida
  4. O nível de layout é muito profundo
  5. Uso excessivo de recursos da CPU e GC frequente

Overdraw

Overdraw descreve que um pixel na tela é desenhado várias vezes no mesmo quadro. Em uma estrutura de IU de vários níveis, se a IU invisível também estiver desenhando, isso fará com que algumas áreas de pixel sejam desenhadas várias vezes. Isso desperdiça muitos recursos de CPU e GPU.

Insira a descrição da imagem aqui

Análise mais detalhada de overdrawing -> "Android Rendering Performance-Overdrawing" .

Repita o layout

Na árvore de visão, uma vez que algumas mudanças de atributo ocorram em qualquer visão, pode causar uma grande reação em cadeia. Por exemplo, se o tamanho de um botão dobrar repentinamente, isso pode fazer com que a posição da visualização do irmão mude, ou pode fazer com que o tamanho da visualização principal mude. Quando um grande número de operações layout () é freqüentemente chamado e executado, é provável que cause perda de quadros.

Insira a descrição da imagem aqui

Por exemplo, em RelativeLayout, geralmente definimos alguns atributos como alignTop, alignBelow, etc., conforme mostrado na figura:

Insira a descrição da imagem aqui

Para obter a posição exata da vista, as seguintes etapas precisam ser passadas. Primeiro, a subvisualização acionará a operação para calcular sua própria posição e, em seguida, RelativeLayout usa as informações de posição calculadas anteriormente para ajustar o limite, conforme mostrado nas duas imagens a seguir:

Insira a descrição da imagem aqui

Após as 2 etapas acima, o RelativeLayout acionará imediatamente a segunda operação layout () para determinar a posição final e as informações de tamanho de todas as subvisualizações.

Além das duas operações de layout que ocorrem em RelativeLayout, LinearLayout também pode acionar duas operações de layout. Normalmente, LinearLayout terá apenas uma operação de layout, mas assim que o método measureWithLargetChild () for chamado, ele acionará duas operações de layout. Além disso, em geral, GridLayout irá pré-processar automaticamente o relacionamento entre as subvisualizações para evitar dois layouts, mas se algumas subvisualizações em GridLayout usarem atributos complexos, como peso, ainda causará operações de layout repetidas.

Se apenas um pequeno número de layouts repetidos não causar sérios problemas de desempenho, mas se ocorrerem no nó raiz do layout ou em um ListItem no ListView, isso causará problemas de desempenho mais sérios. Como mostrado abaixo:

Insira a descrição da imagem aqui

Renderização repetida

De modo geral, para uma visão opaca, ela só precisa ser renderizada uma vez para exibi-la, mas se essa visão for definida com um valor alfa para obter um efeito translúcido, isso fará com que a visão seja renderizada pelo menos duas vezes. O motivo é que a Visualização contendo alfa precisa saber com antecedência qual é o próximo elemento da Visualização mista e, a seguir, combinar a Visualização superior para realizar o processo de mistura de cores de mesclagem.

Em alguns casos, uma visualização contendo alfa pode fazer com que a visualização pai da visualização na HierarchyView seja redesenhada mais uma vez. Vejamos um exemplo abaixo: As imagens e os títulos secundários no ListView mostrados na figura abaixo têm transparência definida.

Insira a descrição da imagem aqui

Na maioria dos casos, os elementos na tela são renderizados de trás para frente. Na ilustração acima, a imagem de fundo (azul, verde e vermelho) será renderizada primeiro e, em seguida, a imagem do avatar será renderizada. Se o elemento pós-renderizado tiver um valor alfa definido, esse elemento será mesclado com o elemento renderizado na tela. Muitas vezes, definiremos o alfa para toda a View para obter o efeito de animação de esmaecimento. Se o ListView na imagem for processado com um alfa gradualmente decrescente, podemos ver que TextView e outros componentes na ListView irão gradualmente se fundir em a cor de fundo ativada. Mas neste processo, não podemos observar que ele realmente acionou tarefas adicionais de desenho, nosso objetivo é tornar toda a View gradualmente transparente, mas durante o período, o ListView está constantemente fazendo operações de Blending, o que vai causar muitos problemas de desempenho.

Então, como resolver esse tipo de problema? Iremos apresentá-lo mais tarde na seção de otimização de desempenho.

O nível de layout é muito profundo

Normalmente, não podemos evitar layouts repetidos. Nesse caso, devemos tentar manter o nível de hierarquia de visualização relativamente raso, de modo que, mesmo que ocorram layouts repetidos, eles não aumentem os múltiplos de layouts repetidos devido ao layout profundo. Há outro ponto que precisa de atenção especial. Evite chamar requestLayout () a qualquer momento, porque assim que requestLayout for chamado, todos os nós pais do layout serão reprojetados.

Insira a descrição da imagem aqui

Uso excessivo de recursos da CPU e GC frequente

Se a ocupação dos recursos da CPU do sistema for muito restrita, isso causará menos tempo de CPU alocado pelo thread de IU, o que afetará a eficiência de execução do thread de IU e causará problemas como travamento.

Se usarmos um grande número de encadeamentos no APP, e a prioridade do encadeamento for o padrão, será muito fácil fazer com que um grande número de sub-encadeamentos e a interface do usuário preencham os recursos da CPU juntos, causando problemas como travamento.

Além disso, se criarmos objetos temporários com frequência e em grandes números durante o processo de exibição da interface, isso causará GC e operações de coleta de lixo frequentes no sistema.

As operações de coleta de lixo causarão atrasos? A resposta é sim. Isso ocorre porque a criação e destruição de objetos requer tempo de execução e recursos e, neste tipo de problema, a criação do objeto é geralmente no UI thread, o que resulta em uma grande quantidade de tempo de criação de objeto a cada quadro de execução Consumo. E uma vez que o GC é ligado, o encadeamento do GC também ocupará parte dos recursos da CPU, causando o problema de preempção de recursos com o encadeamento da IU. Ao mesmo tempo, o GC geralmente causa um certo período de operação de pausa durante a execução (diferentes versões do Android são diferentes, versões anteriores Ele fará uma pausa duas vezes, quanto maior for a versão, melhor será o desempenho do sistema), o que fará com que o thread de interface do usuário pause por um curto período e cause um congelamento.

Otimização de desempenho de renderização


Otimizar overdraw

A razão fundamental para o overdraw é que vários pixels são empilhados em uma posição de pixel e aguardam para serem desenhados. Podemos usar os seguintes métodos para otimizar:

  • Remova o fundo desnecessário.
  • Use os métodos clipRect e clipPath para reduzir o número de camadas desenhadas.
  • Ao usar temas, não se esqueça de remover o fundo do tema.

Um aspecto muito importante que causa problemas de desempenho é devido a muitas operações de desenho complexas. Podemos usar ferramentas para detectar e corrigir o problema de Overdraw de componentes de UI padrão, mas para componentes de UI altamente personalizados, parece um pouco fraco.

Desenhar atualizações para componentes invisíveis da IU causará Overdraw. Por exemplo, depois que o Nav Drawer desliza para fora da Activity visível na frente, se você continuar a desenhar os componentes da IU que não são visíveis no Nav Drawer, isso leva ao Overdraw. Para resolver esse problema, o sistema Android minimiza o Overdraw, evitando componentes de desenho que são completamente invisíveis. As visualizações que não são visíveis no Nav Drawer não serão executadas e desperdiçarão recursos.

Insira a descrição da imagem aqui

No entanto, para essas visualizações personalizadas complexas (reescrevendo o método onDraw), o sistema Android não pode monitorar e otimizar automaticamente, e não pode evitar o overdraw.

No entanto, podemos usar o método canvas.clipRect () para ajudar o sistema a reconhecer a área visível ao personalizar o componente e reescrever o método onDraw. Este método pode especificar uma área retangular, que só será desenhada dentro da área retangular, e outros áreas serão ignoradas. Esta API pode muito bem ajudar as visualizações personalizadas com vários conjuntos de componentes sobrepostos para controlar a área exibida. Ao mesmo tempo, o método clipRect também pode ajudar a economizar recursos de CPU e GPU. As instruções de desenho fora da área clipRect não serão executadas, mas os componentes com parte do conteúdo na área retangular ainda serão desenhados.

Insira a descrição da imagem aqui

Além do método clipRect, também podemos usar canvas.quickreject () para determinar se ele não intercepta um retângulo, ignorando assim as operações de desenho na área não retangular.

Reduza medições e layout repetidos

No caso do mesmo nível de layout, use LinearLayout em vez de RelativeLayout. Como LinearLayout medirá apenas uma vez por padrão, e RelativeLayout medirá duas vezes; no entanto, quando a visualização LinearLayout tem um atributo de peso, ele também medirá duas vezes. Neste momento, é recomendado usar RelativeLayout.

No caso do mesmo nível de profundidade, a prioridade é a seguinte:

  1. FrameLayout
  2. LinearLayout (não defina o atributo de peso)
  3. Esquema relativo

O atributo de peso não é usado no LinearLayout e apenas
um processo de medição será executado. Se o atributo de peso for usado, o LinearLayout evita as visualizações filho que definiram o atributo de peso na primeira medição e, em seguida, realiza uma segunda medição nelas. Isso mostra que o atributo de peso tem um impacto no desempenho.
Se o peso for definido no layout, o LinearLayout será medido duas vezes, o que obviamente afeta o desempenho, então devemos ser capazes de usá-lo menos quando o peso não for aplicável.

RelativeLayout medirá duas vezes

(1) RelativeLayout é mais lento que LinearLayout porque permite que o View filho chame o processo de medição duas vezes, enquanto o último só precisa ser feito uma vez, mas quando o atributo de peso existe, o último também executa duas medições.

(2) Se a altura do filho View do RelativeLayout for diferente do RelativeLayout, isso causará problemas de eficiência.Você pode usar preenchimento em vez de margem para otimizar esse problema.

(3) No caso de não responder ao nível de profundidade, use Linearlayout em vez de RelativeLayout.

Repita a otimização da renderização

Ao explicar as causas dos problemas de desempenho de renderização, já sabemos que uma View opaca só precisa ser renderizada uma vez para exibi-la, e se a View estiver configurada com um valor alfa, ela precisará ser renderizada pelo menos duas vezes (a razão é que a visualização contendo alfa precisa ser renderizada com antecedência Saiba qual é o próximo elemento da visualização mista e, em seguida, combine a visualização superior para realizar o processo de mistura de cores de mesclagem.), mesmo em alguns casos, uma Visualização contendo alfa pode acionar o vista-pai na árvore de vista para ser tudo Um redesenho adicional.

Então, como podemos otimizar esse tipo de problema?

Hmm, o primeiro método é muito simples, tente minimizar o uso de efeitos translúcidos e reduzir o uso de alfa do View.

No entanto, às vezes precisamos de efeitos translúcidos, como podemos evitar o problema de renderização repetida?

Seguindo o exemplo acima (ListView faz o processo de diminuir o alfa gradualmente), vamos analisar a solução:

Podemos primeiro desenhar os elementos na Visualização da maneira usual de trás para frente, mas não exibir diretamente na tela, mas usar o pré-processamento da GPU e, em seguida, a renderização da GPU na tela, a GPU pode visualizar a interface Girar os dados brutos diretamente nele, defina a transparência e assim por diante. Usando a GPU para renderizar, embora a primeira operação consuma mais tempo do que desenhar diretamente na tela, uma vez que os dados de textura original são gerados, as operações subsequentes economizarão tempo e esforço.

Insira a descrição da imagem aqui

Como podemos deixar a GPU renderizar uma determinada visualização? Podemos usar o método setLayerType para especificar como o View deve ser renderizado. A partir do SDK 16, também podemos usar ViewPropertyAnimator.alpha (). WithLayer () para especificar. Como mostrado abaixo:

Insira a descrição da imagem aqui

Outro exemplo é uma visão que contém uma área sombreada.Este tipo de visão não tem os problemas que mencionamos anteriormente porque eles não têm um relacionamento em cascata.

Insira a descrição da imagem aqui

Para permitir que o renderizador saiba dessa situação e evitar ocupar espaço extra da memória da GPU para este tipo de visualização, podemos fazer as seguintes configurações:

Insira a descrição da imagem aqui

Após as configurações acima, o desempenho pode ser significativamente melhorado, conforme mostrado na figura a seguir:

Insira a descrição da imagem aqui

O nível de layout é uma otimização muito profunda

Devemos tentar manter o nível de Hierarquia de visualização relativamente raso, de modo que, mesmo que ocorra um layout repetido, isso não aumente o múltiplo do layout repetido devido ao layout profundo.

Evite chamar requestLayout ()

Evite chamar o método requestLayout () a qualquer momento, porque assim que requestLayout for chamado, todos os nós pais do layout serão reprojetados. Quanto mais complexo o layout e mais profundo o nível do layout, maior será a perda de desempenho.

Para o princípio de requestLayou, consulte "Análise do código-fonte do processo de redesenho iniciado pelo RequestLayout de View (Android Q)" .

Use a tag de mesclagem

Use mesclar para reduzir níveis desnecessários.

cenas a serem usadas:

  1. O uso mais comum de mesclar é com a tag de inclusão. Dessa forma, quando o layout for reutilizado, o aninhamento de layout redundante não será adicionado e o problema causado apenas pela tag de inclusão será resolvido.
  2. Além disso, ao personalizar a Visualização combinada (por exemplo, herdar de FrameLayout, LinearLayout, etc.), geralmente criamos um layout personalizado e o adicionamos à Visualização personalizada por meio do id do índice. Neste momento, se a tag de mesclagem não for usado, será invisível. Adicionará um nível de aninhamento.

Por exemplo, personalizamos um container View, o nome da classe é TestLayout, herdado de LinearLayout, o layout de preenchimento deste controle personalizado pode usar a tag de mesclagem.

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</merge>

TestLayout herda de LinearLayout, portanto é um LinearLayout em si. Se modificarmos a mesclagem no layout para LinearLayout, haverá 2 aninhamentos LinearLayout, um dos quais é redundante.

Use tags ViewStub

O rótulo é usado para carregamento lento do layout.Quando o sistema encontra o rótulo ViewStub, ele não realiza nenhum processamento (medida, layout, etc.), o que é mais eficiente do que definir a Visualização como oculta e invisível. Renderize quando realmente precisarmos exibir um determinado layout.

Quando o ViewStub se tornar visível ou inflar (), o layout será carregado (substitua o ViewStub).

O carregamento lento de tags ViewStub tem os seguintes benefícios:

  1. Pode evitar o consumo de desempenho da medida de visualização e do layout correspondente ao ViewStub. Só será executado quando for utilizado. Por exemplo, quando o APP é iniciado, sua utilização pode aumentar a velocidade de inicialização.
  2. A vista carregada está em cascata. Configurações inadequadas podem causar problemas como o desenho excessivo. Com o carregamento lento do ViewStub, a renderização não será executada.
  3. Evite o consumo de desempenho ao chamar requestLayout na árvore de exibição.
  4. Evite o consumo de recursos, como criação e inicialização de View, porque ViewStub é um componente leve que consome poucos recursos.

Se não usarmos ViewStub, mas definirmos a View como invisível, a View ocupará uma posição no arquivo de layout, mas o estado da View não é visível, a View ainda criará objetos, será inicializada e ocupará recursos. Se você definir a View como eliminada, a View não ocupará uma posição no arquivo de layout, mas o objeto ainda será criado, será inicializado e ocupará recursos.

Use a visualização personalizada para otimizar o layout

Para alguns designs complexos de IU, se usarmos os componentes de visualização nativos do sistema, às vezes precisamos usar várias camadas de layouts aninhados para conseguir isso. Além disso, se nosso layout for muito complexo, é fácil causar problemas de desempenho de renderização.

Neste momento, uma maneira melhor pode ser projetar uma visualização customizada para implementar funções relacionadas. A Visualização customizada é mais adequada para o nosso negócio e será mais fácil de controlar se houver lógica de interação complexa.

No entanto, se a Visualização personalizada não estiver codificada corretamente, pode facilmente causar problemas de desempenho.

De modo geral, para a Visualização personalizada, podemos cometer os três erros a seguir:

  • Chamar View.invalidate () acionará o redesenho da visualização. Há dois princípios que precisam ser seguidos. O primeiro é acionar o método invalidate apenas quando o conteúdo da visualização muda e o segundo é tentar usar métodos como ClipRect para melhorar o desempenho do desenho.
  • Reduza os elementos de desenho desnecessários ao desenhar. Para esses elementos invisíveis, precisamos evitar o redesenho, tanto quanto possível.
  • Para elementos que não estão na tela, você pode usar Canvas.quickReject para removê-los e evitar o desperdício de recursos da CPU. Além disso, tente usar a GPU para renderizar a IU, o que pode melhorar muito o desempenho geral do programa.

Otimize threads e reduza GC

Recomendações para otimização de discussão

A otimização de threads concentra-se principalmente em dois pontos: controle do número de threads e controle da prioridade das threads.

Para obter mais informações, consulte "Android Performance Optimization-Thread Performance" .

Recomendações para otimização de GC:

  1. Reduza a alocação de objetos e evite criar um grande número de objetos em um curto espaço de tempo.
  2. A reutilização de objetos requer o uso de um pool de reutilização para objetos freqüentemente alocados.
  3. Libere referências a objetos inúteis o mais rápido possível, especialmente objetos grandes e objetos de coleção, e recupere-os a tempo, definindo-os como “As”.
  4. Controle o uso do método de finalização e use classes que substituem a finalização em funções de alta frequência, o que aumentará a carga do GC.

Abaixo estão alguns exemplos de problemas comuns de desempenho causados ​​pelo onDraw:

O método onDraw () é executado no thread de IU. Tente evitar qualquer operação que possa afetar o desempenho no thread de IU. Embora a operação de alocação de memória não exija muitos recursos do sistema, isso não significa que seja gratuita e sem custos. O dispositivo tem uma certa frequência de atualização, o que faz com que o método onDraw de View seja freqüentemente chamado. Se o método onDraw for ineficiente, o problema de ineficiência será ampliado sob o efeito do acúmulo de atualização frequente, e então terá um sério impacto no desempenho.

Insira a descrição da imagem aqui

Se a alocação de memória for realizada no onDraw, isso causará facilmente jitter na memória e o GC será acionado com frequência.

O método de otimização também é muito simples.Normalmente, vamos mover a operação do novo Paint em onDraw () para fora, conforme mostrado abaixo:

Insira a descrição da imagem aqui

Ferramenta de análise de desempenho de renderização


Agora que entendemos os problemas de desempenho relacionados à renderização e como resolvê-los, há outro ponto importante, ou seja, como descobrir se há um problema com o desempenho de renderização.

Eu recomendo algumas ferramentas muito úteis aqui.

Análise de CPU demorada: CPU Profiler

"Introdução e uso detalhado da ferramenta de análise de desempenho do gerenciador de perfis de CPU do Android Studio"

Análise de nível de layout: Layout Inspector

"Ferramenta de análise de layout Android Layout Inspector (para resolver os problemas de desempenho causados ​​pelo layout)"

Modo de renderização GPU

"Como usar o" modo de renderização da GPU "para localizar o problema travado"

Análise demorada: Systrace

"Explicação detalhada do uso da ferramenta de análise de desempenho Systrace"

Análise demorada: Perfetto

"Ferramenta de análise de desempenho do Android - introdução ao Perfetto"

Resumindo


Este artigo será dividido nas seguintes partes para analisar e resumir o desempenho de renderização: taxa de quadros e problemas de desempenho de renderização, causas de problemas de desempenho de renderização, métodos de otimização de desempenho de renderização, ferramentas de análise.

A meta de desempenho de desenvolver um aplicativo é manter 60fps, o que significa que você só tem 1000/60 = 16,67ms por quadro para processar todas as tarefas. Se não houver maneira de completar a tarefa deste quadro em 16 ms, ocorrerá perda de quadros. Quanto mais quadros forem eliminados, mais grave será a situação de congelamento que o usuário enfrentará.

Os motivos para o desempenho de renderização são divididos em:

  1. Overdraw
  2. Repita o layout
  3. Renderização repetida
  4. O nível de layout é muito profundo
  5. Uso excessivo de recursos da CPU e GC frequente

Por diferentes razões, o artigo oferece sugestões de otimização correspondentes e, finalmente, recomenda ferramentas úteis de teste de desempenho.

Espero que este artigo possa ser útil para todos e pode ajudá-lo a melhorar o desempenho de renderização de seu APP.


** PS: Para conteúdo mais interessante, verifique -> "Otimização de desempenho do Android"
** PS: Para conteúdo mais interessante, verifique -> "Otimização de desempenho do Android"
** PS: Para conteúdo mais interessante, verifique- -> "Otimização de desempenho do Android"

Acho que você gosta

Origin blog.csdn.net/u011578734/article/details/110979830
Recomendado
Clasificación