Monitoramento de desempenho dos lançamentos de recursos

1. Visão geral

Neste codelab, você aprenderá a monitorar o desempenho do seu app durante o lançamento de um recurso. Nosso app de exemplo terá uma funcionalidade básica e está configurado para exibir uma imagem de plano de fundo diferente com base em uma sinalização da Configuração remota do Firebase. Vamos analisar a instrumentação de rastros para monitorar o desempenho do app, o lançamento de uma mudança de configuração, o monitoramento do efeito e como podemos melhorar o desempenho.

Conteúdo

  • Como adicionar o Monitoramento de desempenho do Firebase ao seu app para dispositivos móveis e ter métricas prontas para uso (como horário de início do app e frames lentos ou congelados)
  • Como adicionar traces personalizados para entender os caminhos de código críticos das jornadas do usuário
  • Como usar o painel do Monitoramento de desempenho para entender suas métricas e rastrear alterações importantes, como o lançamento de um recurso.
  • Como configurar alertas de desempenho para monitorar suas principais métricas
  • Como implementar uma alteração na Configuração remota do Firebase

Pré-requisitos

  • Android Studio 4.0 ou mais recente
  • Um Android Emulator com o nível 16 da API ou mais recente.
  • Java versão 8 ou mais recente
  • Conhecimentos básicos da Configuração remota do Firebase

2. Configurar o projeto de amostra

Fazer o download do código

Execute o comando a seguir para clonar o exemplo de código deste codelab. Uma pasta chamada codelab-perf-rc-android será criada na sua máquina:

$ git clone https://github.com/FirebaseExtended/codelab-feature-rollout-performance.git

Se você não tiver o Git na máquina, também poderá fazer o download do código diretamente do GitHub.

Importe o projeto na pasta firebase-perf-rc-android-start para o Android Studio. Você provavelmente vai receber algumas exceções de tempo de execução ou um aviso sobre um arquivo google-services.json ausente. Vamos corrigir isso na próxima seção.

Neste codelab, você vai usar o plug-in do Firebase Assistente para registrar seu app Android com um projeto do Firebase e adicionar os arquivos de configuração, plug-ins e dependências necessários ao seu projeto do Android. Tudo isso sem sair do Android Studio.

Conectar seu app ao Firebase

  1. Acesse Android Studio/Help > Check for updates para confirmar se você está usando as versões mais recentes do Android Studio e do Firebase Assistente.
  2. Selecione Tools > Firebase para abrir o painel Assistente.

c0e42ef063d21eab.png

  1. Escolha Monitoramento de desempenho para adicionar ao app e clique em Introdução ao Monitoramento de desempenho.
  2. Clique em Conectar ao Firebase para conectar seu projeto do Android ao Firebase. Isso abre o Console do Firebase no seu navegador.
  3. No Console do Firebase, clique em Adicionar projeto e insira o nome de um projeto do Firebase. Se você já tiver um projeto do Firebase, selecione-o. Clique em Continuar e aceite os termos para criar o projeto e um novo app do Firebase.

Em seguida, você verá uma caixa de diálogo para Conectar seu novo app do Firebase ao projeto do Android Studio.

51a549ebde2fe57a.png

  1. Clique em Conectar.
  2. Abra o Android Studio. No painel Assistente, você verá a confirmação de que seu app está conectado ao Firebase.

40c24c4a56a45990.png

Adicionar o Monitoramento de desempenho ao seu app

No painel Assistant no Android Studio, clique em Add Performance Monitoring to your app.

Uma caixa de diálogo Accept Changes vai aparecer. Depois disso, o Android Studio vai sincronizar seu app para garantir que todas as dependências necessárias tenham sido adicionadas.

3046f3e1f5fea06f.png

Por fim, uma mensagem de êxito vai aparecer no painel Assistant do Android Studio informando que todas as dependências estão configuradas corretamente.

62e79fd18780e320.png

Como uma etapa extra, ative a geração de registros de depuração seguindo as instruções em "(Opcional) Ativar a geração de registros de depuração". As mesmas instruções também estão disponíveis na documentação pública.

3. Executar o aplicativo

Agora você verá o arquivo google-services.json no diretório do módulo (nível do app) e o app será compilado. No Android Studio, clique em Run > Run 'app' para criar e executar o app no Android Emulator.

Quando o app está em execução, primeiro você vê uma tela de apresentação como esta:

ffbd413a6983b205.png

Após alguns segundos, a página principal com a imagem padrão será exibida:

d946cab0df319e50.png

O que está acontecendo nos bastidores?

A tela de apresentação é implementada na SplashScreenActivity e faz o seguinte:

  1. Em onCreate(), inicializamos as configurações da Configuração remota do Firebase e buscamos os valores de configuração que você vai definir no painel da Configuração remota mais adiante neste codelab.
  2. Em executeTasksBasedOnRC(), lemos o valor de configuração da sinalização seasonal_image_url. Se um URL for fornecido pelo valor de configuração, o download da imagem será feito de maneira síncrona.
  3. Quando o download for concluído, o app navegará para a MainActivity e chamará finish() para encerrar o SplashScreenActivity.

No MainActivity, se seasonal_image_url for definido pela Configuração remota, o recurso será ativado e a imagem transferida por download será exibida como o plano de fundo da página principal. Caso contrário, a imagem padrão (mostrada acima) será exibida.

4. Definir a Configuração remota

Agora que o app está em execução, configure a nova flag de recurso.

  1. No painel esquerdo do Console do Firebase, localize a seção Engajamento e clique em Configuração remota.
  2. Clique no botão Criar configuração para abrir o formulário de configuração e adicionar seasonal_image_url como a chave do parâmetro.
  3. Clique em Adicionar descrição e digite esta descrição: Shows a seasonal image (replaces default) in the main page when the restaurant list is empty.
  4. Clique em Adicionar novo -> Valor condicional -> Criar nova condição.
  5. Para o nome da condição, insira Seasonal image rollout.
  6. Para a seção Applies if..., selecione User in random percentile <= 0%. Deixe o recurso desativado até que tudo esteja pronto para o lançamento em uma etapa posterior.
  7. Clique em Criar condição. Você vai usar essa condição mais tarde para lançar o novo recurso para seus usuários.

7a07526eb9e81623.png

  1. Abra Crie seu primeiro formulário de parâmetro e localize o campo Valor para lançamento sazonal de imagens. Insira o URL de onde será feito o download da imagem sazonal: https://images.unsplash.com/photo-1552691021-7043334e0b51
  2. Deixe o valor padrão como uma string vazia. Isso significa que a imagem padrão na base de código será mostrada em vez de uma imagem transferida por download de um URL.
  3. Clique em Salvar.

99e6cd2ebcdced.png

Observe que a nova configuração é criada como um rascunho.

  1. Clique em Publicar alterações e confirme as alterações na parte superior para atualizar o app.

39cd3e96d370c7ce.png

5. Adicionar monitoramento para o tempo de carregamento de dados

Seu app pré-carrega alguns dados antes de mostrar MainActivity e mostra uma tela de apresentação para ocultar esse processo. Você não quer que os usuários esperem muito nessa tela. Normalmente, é benéfico monitorar por quanto tempo a tela de apresentação é exibida.

O Monitoramento de desempenho do Firebase oferece uma maneira de fazer exatamente isso. É possível instrumentar traces de código personalizados para monitorar o desempenho de um código específico no app, como o tempo de carregamento de dados e o tempo de processamento do novo recurso.

Para acompanhar por quanto tempo a tela de apresentação é exibida, adicione um trace de código personalizado a SplashScreenActivity, que é o Activity que implementa a tela de apresentação.

  1. Inicialize, crie e inicie um trace de código personalizado chamado splash_screen_trace:

SplashScreenActivity.java (link em inglês)

// ...
import com.google.firebase.perf.FirebasePerformance;
import com.google.firebase.perf.metrics.Trace;
// ...

public class SplashScreenActivity extends AppCompatActivity {

    private static final String TAG = "SplashScreenActivity";
    private static final String SEASONAL_IMAGE_URL_RC_FLAG = "seasonal_image_url";

    // TODO: Initialize splash_screen_trace
    private final Trace splashScreenTrace = FirebasePerformance.startTrace("splash_screen_trace");
    
    // ...
}
  1. Encerre o rastro no método onDestroy() de SplashScreenActivity:

SplashScreenActivity.java (link em inglês)

@Override
protected void onDestroy() {
    super.onDestroy();

    // TODO: Stop the splash_screen_trace here
    splashScreenTrace.stop();
}

Como o novo recurso faz o download e processa uma imagem, você vai adicionar um segundo trace de código personalizado que vai rastrear o tempo extra adicionado ao SplashScreenActivity.

  1. Inicialize, crie e inicie um trace de código personalizado chamado splash_seasonal_image_processing:

SplashScreenActivity.java (link em inglês)

private void executeTasksBasedOnRC(FirebaseRemoteConfig rcConfig) {
    String seasonalImageUrl = rcConfig.getString(SEASONAL_IMAGE_URL_RC_FLAG);
    Log.d(TAG, SEASONAL_IMAGE_URL_RC_FLAG + ": " + seasonalImageUrl);

    if (!seasonalImageUrl.isEmpty()) {
        // TODO: Start the splash_seasonal_image_processing here
        final Trace seasonalImageProcessingTrace = FirebasePerformance
            .startTrace("splash_seasonal_image_processing");

        // ...
    }
}
  1. Encerre o rastro nos métodos onLoadFailed() e onResourceReady() da RequestListener:

SplashScreenActivity.java (link em inglês)

Glide.with(SplashScreenActivity.this.getApplicationContext())
    .asBitmap()
    .load(seasonalImageUrl)
    .signature(new ObjectKey(Utils.getCacheUUID()))
    .listener(new RequestListener<Bitmap>() {
        @Override
        public boolean onLoadFailed(
            @Nullable GlideException e,
            Object model, Target<Bitmap> target,
            boolean isFirstResource) {

            // TODO: Stop the splash_seasonal_image_processing here
            seasonalImageProcessingTrace.stop();

            launchMainActivity();
            return true;
        }

        @Override
        public boolean onResourceReady(Bitmap resource, Object model,
            Target<Bitmap> target, DataSource dataSource,
            boolean isFirstResource) {

            // TODO: Stop the splash_seasonal_image_processing here
            seasonalImageProcessingTrace.stop();

            launchMainActivity();
            return true;
        }
     })
     .preload();

Agora que você adicionou traces de código personalizados para monitorar a duração da tela de apresentação (splash_screen_trace) e o tempo de processamento do novo recurso (splash_seasonal_image_processing), execute o app no Android Studio novamente. Você verá uma mensagem de geração de registros que contém Logging trace metric: splash_screen_trace, seguida pela duração do rastro. Você não verá uma mensagem de registro de splash_seasonal_image_processing porque ainda não ativou o novo recurso.

6. Adicionar um atributo personalizado ao trace

Nos traces de código personalizados, o Monitoramento de desempenho registra automaticamente os atributos padrão (metadados comuns, como versão do app, país, dispositivo etc.) para filtrar os dados do trace no Console do Firebase. Também é possível adicionar e monitorar atributos personalizados.

No seu app, você acabou de adicionar dois traces de código personalizados para monitorar a duração da tela de apresentação e o tempo de processamento do novo recurso. Um fator que pode afetar essas durações é se a imagem exibida é a imagem padrão ou se é necessário fazer o download dela de um URL. E, quem sabe, eventualmente você pode ter URLs diferentes a partir dos quais faz o download de uma imagem.

Então, vamos adicionar um atributo personalizado que representa o URL da imagem sazonal a esses traces de código personalizados. Dessa forma, é possível filtrar os dados de duração por esses valores mais tarde.

  1. Adicione o atributo personalizado (seasonal_image_url_attribute) para splash_screen_trace no início do método executeTasksBasedOnRC:

SplashScreenActivity.java (link em inglês)

private void executeTasksBasedOnRC(FirebaseRemoteConfig rcConfig) {
    String seasonalImageUrl = rcConfig.getString(SEASONAL_IMAGE_URL_RC_FLAG);
    Log.d(TAG, SEASONAL_IMAGE_URL_RC_FLAG + ": " + seasonalImageUrl);

    // TODO: Add a custom attribute "seasonal_image_url_attribute" to splash_screen_trace
    if (seasonalImageUrl.isEmpty()) {
        splashScreenTrace.putAttribute("seasonal_image_url_attribute", "unset");
    } else {
        splashScreenTrace.putAttribute("seasonal_image_url_attribute", seasonalImageUrl);
    }

    // ...
}
  1. Adicione o mesmo atributo personalizado para splash_seasonal_image_processing logo após a chamada de startTrace("splash_seasonal_image_processing"):

SplashScreenActivity.java (link em inglês)

if (!seasonalImageUrl.isEmpty()) {
    // TODO: Start the splash_seasonal_image_processing here
    final Trace seasonalImageProcessingTrace = FirebasePerformance
        .startTrace("splash_seasonal_image_processing");

    // TODO: Add a custom attribute "seasonal_image_url_attribute" to splash_seasonal_image_processing
    seasonalImageProcessingTrace
        .putAttribute("seasonal_image_url_attribute", seasonalImageUrl);

    // ...
}

Agora que você adicionou um atributo personalizado (seasonal_image_url_attribute) para os dois traces personalizados (splash_screen_trace e splash_seasonal_image_processing), execute o app no Android Studio novamente. Você verá uma mensagem de registro com Setting attribute 'seasonal_image_url_attribute' to 'unset' on trace 'splash_screen_trace'.. Você ainda não ativou o parâmetro da Configuração remota seasonalImageUrl. Por isso, o valor do atributo é unset.

O SDK do Monitoramento de desempenho coletará os dados de rastreamento e os enviará ao Firebase. Confira os dados no painel Desempenho do Console do Firebase. Explicaremos esse assunto em detalhes na próxima etapa do codelab.

7. Configurar o painel do Monitoramento de desempenho

Configurar o painel para monitorar o recurso

No Console do Firebase, selecione o projeto que tem o app Friendly Eats.

No painel à esquerda, localize a seção Versão e monitoramento e clique em Desempenho.

O painel Performance vai aparecer nos primeiros pontos de dados. O SDK do Monitoramento de desempenho coleta dados de desempenho do seu app e os exibe minutos após a coleta.

f57e5450b70034c9.png

Esse quadro é onde você pode acompanhar as principais métricas do app. A visualização padrão inclui a duração do trace do tempo de inicialização, mas é possível adicionar as métricas mais importantes. Como você está acompanhando o novo recurso adicionado, é possível personalizar seu painel para exibir a duração do trace de código personalizado splash_screen_trace.

  1. Clique em uma das caixas vazias Selecionar uma métrica.
  2. Na caixa de diálogo, selecione o tipo de trace de Traces personalizados e o nome splash_screen_trace do trace.

1fb81f4dba3220e0.png

  1. Clique em Selecionar métrica para exibir a duração de splash_screen_trace adicionada ao seu painel.

Você pode usar essas mesmas etapas para adicionar outras métricas importantes para ver rapidamente como o desempenho deles muda ao longo do tempo e até mesmo com versões diferentes.

1d465c021e58da3b.png

O quadro de métricas é uma ferramenta eficiente para acompanhar o desempenho das principais métricas apresentadas pelos usuários. Neste codelab, você tem um pequeno conjunto de dados em um período curto. Portanto, você usará outras visualizações do painel para entender o desempenho do lançamento do recurso.

8. Lançar seu recurso

Agora que você configurou o monitoramento, está tudo pronto para implementar a alteração da Configuração remota do Firebase (seasonal_image_url) que você configurou anteriormente.

Para lançar uma alteração, volte à página Configuração remota no Console do Firebase para aumentar o percentil do usuário da sua condição de segmentação. Normalmente, você lançaria novos recursos para uma pequena parte dos usuários e os aumentaria apenas quando tiver certeza de que não há problemas com eles. No entanto, neste codelab, você é os únicos usuários do app, então pode mudar o percentil para 100%.

  1. Clique na guia Condições na parte superior da página.
  2. Clique na condição Seasonal image rollout adicionada anteriormente.
  3. Mude o percentil para 100%.
  4. Clique em Salvar condição.
  5. Clique em Publicar alterações e confirme as mudanças.

70f993502b27e7a0.png

No Android Studio, reinicie o app no emulador para conferir o novo recurso. Após a tela de apresentação, o novo estado vai aparecer na tela principal vazia.

b0cc91b6e48fb842.png

9. Verificar as mudanças no desempenho

Agora vamos verificar o desempenho do carregamento da tela de apresentação usando o painel Desempenho no Console do Firebase. Nesta etapa do codelab, você usará diferentes partes do painel para visualizar dados de desempenho.

  1. Na guia Painel principal, role para baixo até a tabela de traces e clique na guia Traces personalizados. Nesta tabela, você verá os traces de código personalizados adicionados anteriormente, além de alguns traces prontos para uso.
  2. Agora que você ativou o novo recurso, procure o trace de código personalizado splash_seasonal_image_processing, que mediu o tempo necessário para fazer o download e processar a imagem. O valor de Duration do trace mostra que o download e o processamento levam um tempo considerável.

439adc3ec71805b7.png

  1. Como você tem dados para splash_seasonal_image_processing, pode adicionar a duração desse trace ao seu quadro de métricas na parte superior da guia Painel.

Assim como antes, clique em uma das caixas vazias Selecione uma métrica. Na caixa de diálogo, selecione o tipo de trace Traces personalizados e o nome splash_seasonal_image_processing do trace. Por fim, clique em Selecionar métrica para adicioná-la ao quadro.

7fb64d2340410576.png

  1. Para confirmar melhor as diferenças, examine os dados de splash_screen_trace. Clique no card splash_screen_trace no quadro de métricas e em Ver detalhes da métrica.

b1c275c30679062a.png

  1. Na página de detalhes, você verá uma lista de atributos no canto inferior esquerdo, incluindo aquele que você criou anteriormente. Clique no atributo personalizado seasonal_image_url_attribute para conferir a duração da tela de apresentação de cada URL de imagem sazonal à direita:

8fa1a69019bb045e.png

  1. Os valores de duração da tela de apresentação provavelmente serão um pouco diferentes dos da captura de tela acima, mas é provável que você tenha uma duração mais longa quando a imagem for transferida por download de um URL em vez de usar a imagem padrão (representada por "não definido").

Neste codelab, o motivo para essa duração maior pode ser simples, mas, em um app real, pode não ser tão óbvio. Os dados de duração coletados serão de dispositivos diferentes, que executam o app em diversas condições de conexão de rede. Essas condições podem ser piores do que o esperado. Vamos analisar como você investigaria esse problema se esta fosse uma situação real.

  1. Clique em Performance na parte de cima da página para voltar à guia principal do Painel: 640b696b79d90103.png
  2. Na tabela de traces na parte inferior da página, clique na guia Solicitações de rede. Nesta tabela, você verá todas as solicitações de rede do seu app agregadas em padrões de URL, incluindo o padrão de URL images.unsplash.com/**. Se você comparar o valor desse tempo de resposta com o tempo total necessário para o download e o processamento da imagem (ou seja, a duração do rastro splash_seasonal_image_processing), notará que uma grande parte do tempo é gasto no download da imagem.

6f92ce0f23494507.png

Descobertas de desempenho

Ao usar o Monitoramento de desempenho do Firebase, você notou o seguinte impacto nos usuários finais com o novo recurso ativado:

  1. O tempo gasto em SplashScreenActivity aumentou.
  2. A duração de splash_seasonal_image_processing foi muito grande.
  3. O atraso foi devido ao tempo de resposta para o download da imagem e ao tempo de processamento correspondente necessário para a imagem.

Na próxima etapa, você vai reduzir o impacto no desempenho revertendo o recurso e identificando como melhorar a implementação dele.

10. Reverter o recurso

Não é recomendável aumentar o tempo de espera dos usuários durante a tela de apresentação. Um dos principais benefícios da Configuração remota é a capacidade de pausar e reverter o lançamento sem precisar lançar outra versão para os usuários. Isso permite que você reaja rapidamente a problemas (como os problemas de desempenho descobertos na última etapa) e minimize o número de usuários insatisfeitos.

Como uma mitigação rápida, você redefinirá o percentil de lançamento como 0 para que todos os usuários vejam a imagem padrão novamente:

  1. Volte para a página Configuração remota no Console do Firebase.
  2. Clique em Condições na parte de cima da página.
  3. Clique na condição Seasonal image rollout adicionada anteriormente.
  4. Mude o percentil para 0%.
  5. Clique em Salvar condição.
  6. Clique em Publicar alterações e confirme as mudanças.

18c4f1cbac955a04.png

Reinicie o app no Android Studio. A tela principal do estado original vazio será mostrada:

d946cab0df319e50.png

11. Corrigir os problemas de desempenho

Você descobriu no codelab que o download de uma imagem para a tela de apresentação estava causando lentidão para o app. Analisando mais de perto a imagem transferida, você percebe que está usando a resolução original da imagem, que era superior a 2 MB. Uma solução rápida para seu problema de desempenho é reduzir a qualidade para uma resolução mais adequada, de modo que o download da imagem demore menos tempo.

Implementar o valor da Configuração remota novamente

  1. Volte para a página Configuração remota no Console do Firebase.
  2. Clique no ícone Editar do parâmetro seasonal_image_url.
  3. Atualize o Valor do lançamento sazonal de imagens para https://images.unsplash.com/photo-1552691021-7043334e0b51?w=640 e clique em Salvar.

828dd1951a2ec4a4.png

  1. Clique na guia Condições na parte superior da página.
  2. Clique em Lançamento sazonal de imagens e defina o percentil novamente como 100%.
  3. Clique em Salvar condição.

1974fa3bb789f36c.png

  1. Clique no botão Publicar alterações.

12. Teste a correção e configure alertas

Executar o app localmente

Com o novo valor de configuração definido para usar outro URL de imagem de download, execute o app novamente. Desta vez, você vai perceber que o tempo gasto na tela de apresentação está menor do que antes.

b0cc91b6e48fb842.png

Conferir o desempenho das mudanças

Volte ao painel Desempenho no Console do Firebase para ver a aparência das métricas.

  1. Desta vez, você vai usar a tabela de traces para navegar até a página de detalhes. Abaixo da tabela de traces, na guia Traces personalizados, clique no trace personalizado splash_seasonal_image_processing para exibir uma visão mais detalhada da métrica de duração novamente.

2d7aaca03112c062.png

  1. Clique no atributo personalizado seasonal_image_url_attribute para ver o detalhamento dos atributos personalizados novamente. Se você passar o cursor sobre os URLs, vai encontrar um valor que corresponde ao novo URL da imagem de tamanho reduzido: https://images.unsplash.com/photo-1552691021-7043334e0b51?w=640 (com ?w=640 no final). O valor de duração associado a esta imagem é consideravelmente menor do que o valor da imagem anterior e é mais aceitável para seus usuários.

10e30c037a4237a2.png

  1. Agora que você melhorou o desempenho da tela de apresentação, configure alertas para receber notificações quando um rastro exceder um limite definido por você. Abra o painel Desempenho, clique no ícone do menu flutuante (três pontos) para splash_screen_trace e em Configurações de alerta.

4bd0a2a1faa14479.png

  1. Clique no botão para ativar o alerta Duração. Defina o valor do limite um pouco acima do valor exibido para que você receba um e-mail se o splash_screen_trace ultrapassar o limite.
  1. Clique em Salvar para criar o alerta. Role para baixo até a tabela de traces e clique na guia Traces personalizados para verificar se o alerta está ativado.

2bb93639e2218d1.png

13. Parabéns!

Parabéns! Você ativou o SDK do Monitoramento de desempenho do Firebase e coletou traces para medir o desempenho de um novo recurso. Você monitorou as principais métricas de desempenho para o lançamento de um novo recurso e reagiu rapidamente quando um problema de desempenho foi descoberto. Tudo isso foi possível graças à capacidade de alterar configurações com a Configuração remota e monitorar problemas de desempenho em tempo real.

O que aprendemos

  • Como adicionar o SDK do Monitoramento de desempenho do Firebase ao seu app
  • Adicionar um trace de código personalizado ao seu código para medir um recurso específico
  • Definir um parâmetro da Configuração remota e um valor condicional para controlar/lançar um novo recurso
  • Entender como usar o painel de monitoramento de desempenho para identificar problemas durante um lançamento
  • Configurar alertas de desempenho para receber notificações quando o desempenho do app ultrapassar um limite definido

Saiba mais