Meça o tempo de carregamento e a renderização da tela com o Firebase Performance Monitoring

1. Introdução

Última Atualização: 2021/03/11

Por que precisamos medir o desempenho das Visualizações?

As visualizações são uma parte importante dos aplicativos Android que afetam diretamente a experiência do usuário. Por exemplo, sua atividade ou fragmento contém a IU que contém os componentes de visualização com os quais os usuários interagem. Os usuários não podem ver todo o conteúdo da IU até que esteja completamente desenhado na tela. Telas lentas e congeladas prejudicarão diretamente a interação do usuário com seu aplicativo e criarão uma experiência ruim para o usuário.

O Firebase Performance Monitoring não fornece essas métricas de desempenho prontas para usar?

Firebase Monitoramento de desempenho captura automaticamente alguns dados de desempenho out-of-the-box, como seu aplicativo hora de início (ou seja, o tempo de carregamento apenas para sua primeira atividade) eo desempenho de renderização de tela (ou seja, quadros lentos e congelados atividades, mas não para Fragmentos). No entanto, os aplicativos da indústria geralmente não têm muitas atividades, mas sim uma atividade e vários fragmentos. Além disso, muitos aplicativos geralmente implementam suas próprias visualizações personalizadas para casos de uso mais complexos. Portanto, é útil entender como medir o tempo de carregamento e desempenho de renderização de tela de ambas as atividades e Fragmentos de instrumentação vestígios de código personalizado em seu aplicativo. Você pode facilmente estender este codelab para medir o desempenho dos componentes do Custom View.

O que você aprenderá

  • Como adicionar o monitoramento de desempenho do Firebase a um aplicativo Android
  • Compreender o carregamento de uma atividade ou fragmento
  • Como instrumentar rastros de código personalizado para medir o tempo de carregamento de uma atividade ou fragmento
  • Compreendendo a renderização de tela e o que é um quadro lento / congelado
  • Como instrumentar rastreamentos de código personalizado com métricas para registrar telas lentas / congeladas
  • Como visualizar as métricas coletadas no Firebase console

O que você precisará

  • Android Studio 4.0 ou superior
  • Um dispositivo / emulador Android
  • Java versão 8 ou superior

2. Preparação

Obtenha o código

Execute os comandos a seguir para clonar o código de amostra para este codelab. Isto irá criar uma pasta chamada codelab-measure-android-view-performance em sua máquina:

$ git clone https://github.com/FirebaseExtended/codelab-measure-android-view-performance.git
$ cd codelab-measure-android-view-performance

Se você não tem git em sua máquina, também pode baixar o código diretamente do GitHub.

Importar a measure-view-performance-start projeto em Android Studio. Você provavelmente verá alguns erros de compilação ou talvez um aviso sobre a falta google-services.json arquivo. Corrigiremos isso na próxima seção desta etapa.

Neste codelab, usaremos o Assistente Firebase do plugin de registrar nosso aplicativo Android com um projeto Firebase e adicione as necessárias Firebase arquivos de configuração, plugins e dependências para o nosso projeto Android - tudo a partir de Android Studio!

Conecte seu aplicativo ao Firebase

  1. Ir para Android Estúdio / Ajuda> Verificar atualizações para se certificar de que você está usando as últimas versões do Android Studio e Assistente Firebase.
  2. Selecione Ferramentas> Firebase para abrir o painel Assistente.

e791bed0999db1e0.png

  1. Escolha Monitoramento de desempenho para adicionar ao seu aplicativo e clique em Comece com monitoramento de desempenho.
  2. Clique em Conectar para Firebase para conectar seu projeto Android com Firebase (isto irá abrir o console Firebase no seu navegador).
  3. No console Firebase, clique em Adicionar projeto, em seguida, digite um nome de projeto Firebase (se você já tem um projeto Firebase, você pode selecionar o projeto existente em vez). Clique em Continuar e aceitar os termos para criar o projeto Firebase e uma nova Firebase App.
  4. Você deve próxima uma caixa de diálogo para conectar o novo Firebase App ao seu projeto Android Studio.

42c498d28ead2b77.png

  1. Voltar no Android Studio, no painel Assistente, você deve ver a confirmação de que seu aplicativo está conectado a Firebase.

dda8bdd9488167a0.png

Adicionar monitoramento de desempenho ao seu aplicativo

No painel Assistente no Android Studio, clique em Add Monitoramento de desempenho para sua aplicação.

Você deverá ver uma caixa de diálogo para aceitar as alterações após o qual Estúdio Android deve sincronizar seu aplicativo para garantir que todas as dependências necessárias foram adicionadas.

9b58145acc4be030.png

Finalmente, você deve ver a mensagem de sucesso no painel de Assistente em Android Studio que todas as dependências estão configurados corretamente.

aa0d46fc944e0c0b.png

Como um passo adicional, activar o registo de depuração, seguindo as instruções no passo "(Opcional) Ative o registro de depuração". As mesmas instruções também estão disponíveis no documentação pública .

3. Execute o aplicativo

Se você integrou com sucesso seu aplicativo ao SDK do Monitoramento de Desempenho, o projeto agora deve ser compilado. Em Android Studio, clique em Executar> Executar 'app' para criar e executar o aplicativo no seu conectado Android dispositivo / emulador.

O aplicativo tem dois botões que levam você a uma atividade e um fragmento correspondentes, como este:

410d8686b4f45c33.png

Nas etapas a seguir deste codelab, você aprenderá como medir o tempo de carregamento e o desempenho de renderização de tela de sua atividade ou fragmento.

4. Compreender o carregamento de uma atividade ou fragmento

Nesta etapa, aprenderemos o que o sistema está fazendo durante o carregamento de uma Activity ou Fragment.

Compreendendo o carregamento de uma atividade

Para uma atividade, o tempo de carga é definido como o tempo a partir de quando o objeto Activity é criado todo o caminho até o primeiro quadro é completamente desenhado na tela (isto é, quando o usuário verá a UI completa para a atividade pela primeira tempo). Para medir se o seu aplicativo está totalmente desenhado, você pode usar o reportFullyDrawn() método para medir o tempo decorrido entre a inicialização do aplicativo e exibição completa de todos os recursos e vista hierarquias.

Em um nível elevado, quando seu aplicativo chama startActivity(Intent) , o sistema executa automaticamente os seguintes processos. Cada processo leva tempo para ser concluído, o que aumenta a duração do tempo entre a criação da atividade e quando o usuário vê a IU da atividade em sua tela.

c20d14b151549937.png

Compreendendo o carregamento de um fragmento

Semelhante à atividade do tempo de carregamento de um fragmento é definido como o tempo a partir de quando o fragmento se apega à sua actividade de acolhimento todo o caminho até o primeiro quadro para o fragmento View está completamente desenhado na tela.

5. Meça o tempo de carregamento de uma atividade

Atrasos no primeiro frame podem levar a uma experiência ruim para o usuário, portanto, é importante entender quanto atraso no carregamento inicial seus usuários estão enfrentando. Você pode instrumento um traço código personalizado para medir esse tempo de carregamento:

  1. Iniciar o rastreamento de código personalizado (chamado TestActivity-LoadTime ) na classe Atividade assim que o objeto Activity é criado.

TestActivity.java

public class TestActivity extends AppCompatActivity {   
    // TODO (1): Start trace recording as soon as the Activity object is created.
    private final Trace viewLoadTrace = FirebasePerformance.startTrace("TestActivity-LoadTime");

    // ...

}
  1. Substituir o onCreate() callback, e obter a exibição adicionado pelo setContentView() método.
@Override     
public void onCreate(Bundle savedInstanceState) {    
    super.onCreate(savedInstanceState);          

    // Current Activity's main View (as defined in the layout xml file) is inflated after this            
    setContentView(R.layout.activity_test);          

    // ...

    // TODO (2): Get the View added by Activity's setContentView() method.         
    View mainView = findViewById(android.R.id.content);     

    // ...
}
  1. Nós incluímos uma implementação de FistDrawListener , que tem dois retornos de chamada: onDrawingStart() e onDrawingFinish() (veja a próxima seção abaixo para mais detalhes sobre FirstDrawListener e que podem afetar o seu desempenho). Registre o FirstDrawListener no final da Atividade onCreate() callback. Você deve interromper o viewLoadTrace na onDrawingFinish() callback.

TestActivity.java

    // TODO (3): Register the callback to listen for first frame rendering (see
    //  "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when View drawing is
    //  finished.
    FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {              
        @Override             
        public void onDrawingStart() {       
          // In practice you can also record this event separately
        }

        @Override             
        public void onDrawingFinish() {
            // This is when the Activity UI is completely drawn on the screen
            viewLoadTrace.stop();             
        }         
    });
  1. Execute novamente o aplicativo. Em seguida, filtrar a logcat com "o registro de rastreamento métrica". Toque no LOAD ACTIVITY botão e olhar para os logs como abaixo:
I/FirebasePerformance: Logging trace metric: TestActivity-LoadTime (duration: XXXms)

🎉 Parabéns! Você mediu com sucesso o tempo de carregamento de uma atividade e relatou esses dados ao Firebase Performance Monitoring. Veremos a métrica registrada no Firebase console posteriormente neste codelab.

Objetivo do FirstDrawListener

Na seção logo acima, registramos um FirstDrawListener . O objectivo da FirstDrawListener é medir quando o primeiro quadro começou e terminou desenho.

Ele implementa o ViewTreeObserver.OnDrawListener e substitui a onDraw() callback que é chamado quando o Ver a árvore está prestes a ser desenhado. Em seguida, envolve o resultado para fornecer dois retornos de utilidade onDrawingStart() e onDrawingFinish() .

O código completo para FirstDrawListener pode ser encontrado neste código-fonte do codelab .

6. Meça o tempo de carregamento de um fragmento

Medir o tempo de carregamento de um Fragment é semelhante a como o medimos para uma Activity, mas com algumas pequenas diferenças. Mais uma vez, vamos instrumento um traço de código personalizado :

  1. Substituir o onAttach() callback e começar a gravar o seu fragmentLoadTrace . Vamos nomear este traço Test-Fragment-LoadTime .

Conforme explicado em uma etapa anterior, o objeto Fragment pode ser criado a qualquer momento, mas torna-se ativo somente quando é anexado à sua Activity host.

TestFragment.java

public class TestFragment extends Fragment {

   // TODO (1): Declare the Trace variable.
   private Trace fragmentLoadTrace;

   @Override
   public void onAttach(@NonNull Context context) {
       super.onAttach(context);

       // TODO (2): Start trace recording as soon as the Fragment is attached to its host Activity.
       fragmentLoadTrace = FirebasePerformance.startTrace("TestFragment-LoadTime");
   }
  1. Registre o FirstDrawListener na onViewCreated() callback. Em seguida, semelhante ao exemplo de Actividade, parar o rastreio no onDrawingFinish() .

TestFragment.java

@Override
public void onViewCreated(@NonNull View mainView, Bundle savedInstanceState) {
   super.onViewCreated(mainView, savedInstanceState);

   // ...

   // TODO (3): Register the callback to listen for first frame rendering (see
   //  "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when view drawing is
   //  finished.
   FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {

       @Override
       public void onDrawingStart() {
           // In practice you can also record this event separately
       }

       @Override
       public void onDrawingFinish() {
           // This is when the Fragment UI is completely drawn on the screen
           fragmentLoadTrace.stop();
       }
   });
  1. Execute o aplicativo novamente. Em seguida, filtrar a logcat com "o registro de rastreamento métrica". Toque no LOAD FRAGMENT botão e olhar para os logs como abaixo:
I/FirebasePerformance: Logging trace metric: TestFragment-LoadTime (duration: XXXms)

🎉 Parabéns! Você mediu com sucesso o tempo de carregamento de um Fragment e relatou esses dados ao Firebase Performance Monitoring. Veremos a métrica registrada no Firebase console posteriormente neste codelab.

7. Compreendendo a renderização de tela e o que é um quadro lento / congelado

Renderização da IU é o ato de gerar um quadro a partir do seu aplicativo e exibi-lo na tela. Para garantir que a interação do usuário com seu aplicativo é suave, a sua aplicação deve processar quadros em menos de 16ms para atingir 60 quadros por segundo ( por que 60fps? ). Se seu aplicativo sofre de renderização lenta da IU, o sistema é forçado a pular quadros e o usuário perceberá gagueira em seu aplicativo. Chamamos isso Jank.

Da mesma forma, quadros congelados são quadros de interface do usuário que levam mais de 700 ms para processar. Esse atraso é um problema porque seu aplicativo parece estar travado e não responde à entrada do usuário por quase um segundo inteiro enquanto o quadro está sendo renderizado.

8. Meça os quadros Lento / Congelado de um Fragmento

Firebase Monitoramento de desempenho captura automaticamente quadros lento / congelados para uma atividade (mas somente se ele é acelerado por hardware). No entanto, esse recurso não está disponível para Fragments. Os quadros lentos / congelados de um fragmento é definido como os quadros lentos / congelado para toda a actividade entre os onFragmentAttached() e onFragmentDetached() chamadas de retorno do ciclo de vida do fragmento.

Tomando motivação do AppStateMonitor classe (que é uma parte do Monitoramento de desempenho SDK responsável pela gravação vestígios de tela de Atividade), implementamos o ScreenTrace classe (que é parte deste codelab repo código fonte). ScreenTrace classe pode ser ligado a da Atividade FragmentManager ciclo de vida callback 's para captura lentos / quadros congelados. Esta classe fornece duas APIs públicas:

  • recordScreenTrace() : Inicia a gravação de um traço tela
  • sendScreenTrace() : Pára a gravação de um traço tela e atribui métricas personalizadas para log Total, lenta, e congelados quadro contagem

Anexando essas métricas personalizados, vestígios de tela para Fragmentos podem ser tratadas da mesma forma que os traços de tela para uma atividade e pode ser exibido juntamente com outros traços de renderização de tela no painel de desempenho do console Firebase.

Veja como registrar rastreamentos de tela para seu Fragment:

  1. Inicializar o ScreenTrace classe em sua atividade que hospeda o Fragmento.

MainActivity.java

// Declare the Fragment tag
private static final String FRAGMENT_TAG = TestFragment.class.getSimpleName();

// TODO (1): Declare the ScreenTrace variable.
private ScreenTrace screenTrace;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // TODO (2): Initialize the ScreenTrace variable.
    screenTrace = new ScreenTrace(this, FRAGMENT_TAG);

    // ...
}
  1. Quando você carrega o seu fragmento, para registrar FragmentLifecycleCallbacks e substituir o onFragmentAttached() e onFragmentDetached() chamadas de retorno. Nós fizemos isso por você. Você precisa começar a gravar vestígios de tela no onFragmentAttached() de gravação de retorno de chamada e parar na onFragmentDetached() callback.

MainActivity.java

private final FragmentManager.FragmentLifecycleCallbacks fragmentLifecycleCallbacks =
       new FragmentManager.FragmentLifecycleCallbacks() {

           @Override
           public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {
               super.onFragmentAttached(fm, f, context);

               // TODO (3): Start recording the screen traces as soon as the Fragment is
               //  attached to its host Activity.
               if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
                   screenTrace.recordScreenTrace();
               }
           }

           @Override
           public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {
               super.onFragmentDetached(fm, f);

               // TODO (4): Stop recording the screen traces as soon as the Fragment is
               //  detached from its host Activity.
               if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
                   screenTrace.sendScreenTrace();
               }

               // Unregister Fragment lifecycle callbacks after the Fragment is detached
               fm.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks);
           }
       };
  1. Execute o aplicativo novamente. Em seguida, toque no LOAD FRAGMENT botão. Aguarde alguns segundos, em seguida, clique no back button na barra de navegação inferior.

Filtrar a logcat com "trace Logging métrica", em seguida, olhar para os logs, como a seguir:

I/FirebasePerformance: Logging trace metric: _st_MainActivity-TestFragment (duration: XXXms)

Filtrar a logcat com "FireperfViews", em seguida, olhar para os logs, como a seguir:

D/FireperfViews: sendScreenTrace MainActivity-TestFragment, name: _st_MainActivity-TestFragment, total_frames: XX, slow_frames: XX, frozen_frames: XX

🎉 Parabéns! Você mediu com sucesso os frames lentos / congelados de um fragmento e relatou esses dados ao monitoramento de desempenho do Firebase. Veremos as métricas registradas no Firebase console posteriormente neste codelab.

9. Verifique as métricas no console do Firebase

  1. No logcat, clique no URL do Firebase console para visitar a página de detalhes para um rastreamento. ceb9d5ba51bb6e89.jpeg

Como alternativa, na consola Firebase , selecione o projeto que tem a sua aplicação. No painel esquerdo, localize a seção Lançamento & Monitor, em seguida, clique em desempenho.

  • Na guia Painel principal, desloque-se para a mesa de traços, em seguida, clique na guia traços personalizados. Nesta tabela, você verá os vestígios de código personalizado que adicionou anteriormente além de alguns traços out-of-the-box , como _app_start traço.
  • Encontrar seus dois traços de código personalizado, TestActivity-LoadTime e TestFragment-LoadTime . Clique sobre a duração de um ou outro para ver mais detalhes sobre os dados coletados.

a0d8455c5269a590.png

  1. A página de detalhes do rastreamento do código personalizado mostra informações sobre a duração do rastreamento (ou seja, o tempo de carregamento medido).

5e92a307b7410d8b.png

  1. Você também pode visualizar os dados de desempenho de seu rastreamento de tela personalizado.
  • Volte para a guia Painel principal, desloque-se para a mesa de traços, em seguida, clique na guia de renderização da tela. Nesta tabela, você verá os vestígios de tela personalizada que adicionou anteriormente acrescido de quaisquer vestígios de tela out-of-the-box , como MainActivity traço.
  • Encontre o seu traço tela personalizada, MainActivity-TestFragment . Clique no nome do traço para visualizar os dados agregados de renderização lenta e quadros congelados.

ee7890c7e2c28740.png

10. parabéns

Parabéns! Você mediu com sucesso o tempo de carregamento e o desempenho de renderização da tela de uma atividade e um fragmento usando o Firebase Performance Monitoring!

O que você conseguiu

Qual é o próximo

O Firebase Performance oferece mais maneiras de medir o desempenho do seu app, além do rastreamento personalizado. Ele mede automaticamente o tempo de inicialização de aplicativos, app-in-primeiro plano, e os dados de desempenho app-em-fundo . É hora para você verificar essas métricas no Console Firebase .

Além disso, ofertas Firebase desempenho HTTP automática / S rede de monitoramento pedido . Com isso, você pode facilmente instrumentar solicitações de rede sem escrever uma única linha de código. Você pode tentar enviar alguns pedidos de rede de seu aplicativo e encontrar as métricas no console de Firebase ?

Bônus

Agora que você sabe como medir o tempo de carregamento e tela de desempenho de renderização do seu Activity / Fragmento usando traços de código personalizado, você pode explorar a nossa base de códigos abertos para ver se você pode capturar essas métricas fora da caixa para qualquer atividade / Fragmento isso faz parte do app? Sinta-se à vontade para enviar o PR se desejar :-)

11. Bonus Learning

Entender o que está acontecendo durante o carregamento de uma atividade ajudará você a entender melhor as características de desempenho do seu aplicativo. Em uma etapa anterior, descrevemos em alto nível o que acontece durante o carregamento de uma atividade, mas o diagrama a seguir descreve cada fase com muito mais detalhes.

cd61c1495fad7961.png