1. Introdução
Última atualização: 11/03/2021
Por que precisamos medir o desempenho das Views?
As visualizações são uma parte fundamental dos aplicativos Android que afetam diretamente a experiência do usuário. Por exemplo, sua atividade ou fragmento contém a UI que contém os componentes de visualização com os quais os usuários interagem. Os usuários não conseguem ver todo o conteúdo da IU até que ele 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 Monitoramento de desempenho do Firebase não fornece essas métricas de desempenho prontas para uso?
O Firebase Performance Monitoring captura automaticamente alguns dados de desempenho prontos para uso, como o horário de início do aplicativo (ou seja, o tempo de carregamento apenas da primeira atividade) e o desempenho de renderização da tela (ou seja, frames lentos e congelados para 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, muitas vezes é útil entender como medir o tempo de carregamento e o desempenho de renderização de tela de atividades e fragmentos instrumentando rastreamentos de código personalizados em seu aplicativo. Você pode estender facilmente este codelab para medir o desempenho dos componentes da visualização personalizada.
O que você aprenderá
- Como adicionar o Firebase Performance Monitoring a um aplicativo Android
- Compreendendo o carregamento de uma atividade ou fragmento
- Como instrumentar rastreamentos de código personalizados para medir o tempo de carregamento de uma atividade ou fragmento
- Noções básicas sobre renderização de tela e o que é um quadro lento/congelado
- Como instrumentar rastreamentos de código personalizados com métricas para registrar telas lentas/congeladas
- Como visualizar as métricas coletadas no console do Firebase
O que você precisará
- Android Studio 4.0 ou superior
- Um dispositivo/emulador Android
- Java versão 8 ou superior
2. Preparando-se
Obtenha o código
Execute os comandos a seguir para clonar o código de amostra deste codelab. Isso 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
Caso não tenha o git em sua máquina, você também pode baixar o código diretamente do GitHub.
Importe o projeto measure-view-performance-start
para o Android Studio. Você provavelmente verá alguns erros de compilação ou talvez um aviso sobre a falta de um arquivo google-services.json
. Corrigiremos isso na próxima seção desta etapa.
Neste codelab, usaremos o plug-in Firebase Assistant para registrar nosso aplicativo Android em um projeto do Firebase e adicionar os arquivos de configuração, plug-ins e dependências necessários do Firebase ao nosso projeto Android, tudo no Android Studio .
Conecte seu aplicativo ao Firebase
- Acesse Android Studio / Ajuda > Verificar atualizações para ter certeza de que está usando as versões mais recentes do Android Studio e do Firebase Assistant.
- Selecione Ferramentas > Firebase para abrir o painel Assistente .
- Escolha Monitoramento de Desempenho para adicionar ao seu aplicativo e clique em Começar com Monitoramento de Desempenho .
- Clique em Conectar ao Firebase para conectar seu projeto Android ao Firebase (isso abrirá o console do Firebase em seu navegador) .
- No console do Firebase, clique em Adicionar projeto e insira um nome de projeto do Firebase (se você já tiver um projeto do Firebase, poderá selecionar esse projeto existente) . Clique em Continuar e aceite os termos para criar o projeto Firebase e um novo aplicativo Firebase.
- Em seguida, você verá uma caixa de diálogo para conectar seu novo aplicativo Firebase ao seu projeto Android Studio.
- De volta ao Android Studio, no painel Assistente , você verá a confirmação de que seu aplicativo está conectado ao Firebase.
Adicione o monitoramento de desempenho ao seu aplicativo
No painel Assistente do Android Studio, clique em Adicionar monitoramento de desempenho ao seu aplicativo .
Você deverá ver uma caixa de diálogo para Aceitar alterações , após a qual o Android Studio deverá sincronizar seu aplicativo para garantir que todas as dependências necessárias foram adicionadas.
Por fim, você deverá ver a mensagem de sucesso no painel Assistente do Android Studio informando que todas as dependências estão configuradas corretamente.
Como etapa adicional, habilite o log de depuração seguindo as instruções na etapa "(Opcional) Habilitar o log de depuração". As mesmas instruções também estão disponíveis na documentação pública .
3. Execute o aplicativo
Se você integrou seu aplicativo com êxito ao SDK do Monitoramento de desempenho, o projeto deverá ser compilado agora. No Android Studio, clique em Executar > Executar 'app' para criar e executar o aplicativo em seu dispositivo/emulador Android conectado.
O aplicativo possui dois botões que levam você a uma Atividade e Fragmento correspondente, como este:
Nas etapas a seguir deste codelab, você aprenderá a medir o tempo de carregamento e o desempenho de renderização de tela da 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 Atividade ou Fragmento.
Compreendendo o carregamento de uma atividade
Para uma Activity, o tempo de carregamento é definido como o tempo a partir do momento em que o objeto Activity é criado até o primeiro quadro ser completamente desenhado na tela ( é quando o usuário verá a UI completa da Activity pela primeira vez). tempo ). Para medir se seu aplicativo está totalmente desenhado, você pode usar o método reportFullyDrawn()
para medir o tempo decorrido entre a inicialização do aplicativo e a exibição completa de todos os recursos e visualizar hierarquias.
Em um nível superior, quando seu aplicativo chama startActivity(Intent)
, o sistema executa automaticamente os seguintes processos. Cada processo leva tempo para ser concluído, o que aumenta o tempo entre a criação da Atividade e o momento em que o usuário vê a IU da Atividade em sua tela.
Compreendendo o carregamento de um fragmento
Semelhante à Atividade, o tempo de carregamento de um Fragmento é definido como o tempo a partir do momento em que o Fragmento é anexado à sua Atividade host até que o Primeiro Quadro da Visualização do Fragmento seja completamente desenhado na tela.
5. Meça o tempo de carregamento de uma atividade
Atrasos no primeiro quadro podem levar a uma experiência ruim para o usuário, por isso é importante entender quanto atraso de carregamento inicial seus usuários estão enfrentando. Você pode instrumentar um rastreamento de código personalizado para medir esse tempo de carregamento:
- Inicie o rastreamento de código personalizado (denominado
TestActivity-LoadTime
) na classe Activity assim que o objeto Activity for 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");
// ...
}
- Substitua o retorno de chamada
onCreate()
e obtenha a View adicionada pelo métodosetContentView()
.
@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);
// ...
}
- Incluímos uma implementação de
FistDrawListener
, que possui dois retornos de chamada:onDrawingStart()
eonDrawingFinish()
(veja a próxima seção abaixo para obter mais detalhes sobreFirstDrawListener
e o que pode afetar seu desempenho) . Registre oFirstDrawListener
no final do retorno de chamadaonCreate()
da Activity. Você deve interromper seuviewLoadTrace
no retorno de chamadaonDrawingFinish()
.
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();
}
});
- Execute novamente o aplicativo. Em seguida, filtre o logcat com " Logging trace metric ". Toque no botão
LOAD ACTIVITY
e procure os registros como abaixo:
I/FirebasePerformance: Logging trace metric: TestActivity-LoadTime (duration: XXXms)
🎉 Parabéns! Você mediu com êxito o tempo de carregamento de uma atividade e relatou esses dados ao Firebase Performance Monitoring. Veremos a métrica registrada no Console do Firebase posteriormente neste codelab.
Objetivo do FirstDrawListener
Na seção acima, registramos um FirstDrawListener
. O objetivo do FirstDrawListener
é medir quando o primeiro quadro começou e terminou o desenho.
Ele implementa ViewTreeObserver.OnDrawListener
e substitui o retorno de chamada onDraw()
que é invocado quando a árvore View está prestes a ser desenhada. Em seguida, ele agrupa o resultado para fornecer dois retornos de chamada de utilitário onDrawingStart()
e onDrawingFinish()
.
O código completo do FirstDrawListener
pode ser encontrado no código-fonte deste codelab .
6. Meça o tempo de carregamento de um fragmento
Medir o tempo de carregamento de um Fragment é semelhante a como medimos para uma Activity, mas com algumas pequenas diferenças. Novamente, instrumentaremos um rastreamento de código personalizado :
- Substitua o retorno de chamada
onAttach()
e comece a gravar seufragmentLoadTrace
. Chamaremos esse rastreamentoTest-Fragment-LoadTime
.
Conforme explicado em uma etapa anterior, o objeto Fragment pode ser criado a qualquer momento, mas ele se torna ativo somente quando é anexado à sua atividade hospedeira.
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");
}
- Registre o
FirstDrawListener
no retorno de chamadaonViewCreated()
. Em seguida, semelhante ao exemplo de Activity, interrompa o rastreamento emonDrawingFinish()
.
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();
}
});
- Execute novamente o aplicativo. Em seguida, filtre o logcat com " Logging trace metric ". Toque no botão
LOAD FRAGMENT
e procure os registros como abaixo:
I/FirebasePerformance: Logging trace metric: TestFragment-LoadTime (duration: XXXms)
🎉 Parabéns! Você mediu com êxito o tempo de carregamento de um fragmento e relatou esses dados ao Firebase Performance Monitoring. Veremos a métrica registrada no Console do Firebase posteriormente neste codelab.
7. Noções básicas sobre renderização de tela e o que é um quadro lento/congelado
UI Rendering é o ato de gerar um frame do seu aplicativo e exibi-lo na tela. Para garantir que a interação do usuário com seu aplicativo seja tranquila, seu aplicativo deve renderizar quadros em menos de 16ms para atingir 60 quadros por segundo ( por que 60fps? ). Se o seu aplicativo apresentar renderização lenta da interface do usuário, o sistema será forçado a pular quadros e o usuário perceberá falhas no seu aplicativo. Chamamos isso de brincadeira .
Da mesma forma, frames congelados são frames de UI que levam mais de 700 ms para serem renderizados. 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 lentos/congelados de um fragmento
O Firebase Performance Monitoring captura automaticamente quadros lentos/congelados para uma atividade ( mas apenas se for acelerada por hardware ). No entanto, esse recurso não está disponível atualmente para Fragmentos. Os quadros lentos/congelados de um Fragmento são definidos como os quadros lentos/congelados para toda a atividade entre os retornos de chamada onFragmentAttached()
e onFragmentDetached()
no ciclo de vida do Fragmento.
Inspirados na classe AppStateMonitor
( que faz parte do SDK do Performance Monitoring responsável por registrar rastreamentos de tela para Activity ), implementamos a classe ScreenTrace
( que faz parte deste repositório de código-fonte do codelab ). A classe ScreenTrace
pode ser conectada ao retorno de chamada do ciclo de vida do FragmentManager
da Activity para capturar quadros lentos/congelados. Esta classe fornece duas APIs públicas:
-
recordScreenTrace()
: Inicia a gravação de um rastreamento de tela -
sendScreenTrace()
: interrompe a gravação de um rastreamento de tela e anexa métricas personalizadas para registrar contagens de quadros totais, lentos e congelados
Ao anexar essas métricas personalizadas, os rastreamentos de tela para fragmentos podem ser tratados da mesma forma que os rastreamentos de tela de uma atividade e podem ser exibidos junto com outros rastreamentos de renderização de tela no painel de desempenho do console do Firebase.
Veja como registrar rastreamentos de tela para seu Fragment:
- Inicialize a classe
ScreenTrace
em sua Activity que hospeda o Fragment.
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);
// ...
}
- Ao carregar seu Fragment, registre-se em
FragmentLifecycleCallbacks
e substitua os retornos de chamadaonFragmentAttached()
eonFragmentDetached()
. Nós fizemos isso por você. Você precisa começar a gravar rastreamentos de tela no retorno de chamadaonFragmentAttached()
e parar a gravação no retorno de chamadaonFragmentDetached()
.
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);
}
};
- Execute novamente o aplicativo. Em seguida, toque no botão
LOAD FRAGMENT
. Aguarde alguns segundos e clique noback button
na barra de navegação inferior.
Filtre o logcat com " Logging trace metric " e procure os logs como abaixo:
I/FirebasePerformance: Logging trace metric: _st_MainActivity-TestFragment (duration: XXXms)
Filtre o logcat com " FireperfViews " e procure os logs como abaixo:
D/FireperfViews: sendScreenTrace MainActivity-TestFragment, name: _st_MainActivity-TestFragment, total_frames: XX, slow_frames: XX, frozen_frames: XX
🎉 Parabéns! Você mediu com êxito os quadros lentos/congelados de um fragmento e relatou esses dados ao Firebase Performance Monitoring. Veremos as métricas registradas no Firebase Console posteriormente neste codelab.
9. Verifique as métricas no console do Firebase
- No logcat, clique no URL do console do Firebase para visitar a página de detalhes de um rastreamento.
Como alternativa, no console do Firebase , selecione o projeto que contém seu aplicativo. No painel esquerdo, localize a seção Liberar e monitorar e clique em Desempenho .
- Na guia Painel principal, role para baixo até a tabela de rastreamentos e clique na guia Rastreamentos personalizados . Nesta tabela, você verá os rastreamentos de código personalizados que adicionamos anteriormente, além de alguns rastreamentos prontos para uso , como o rastreamento
_app_start
. - Encontre seus dois rastreamentos de código personalizados,
TestActivity-LoadTime
eTestFragment-LoadTime
. Clique na Duração de qualquer um para ver mais detalhes sobre os dados coletados.
- A página de detalhes do rastreamento de código personalizado mostra informações sobre a duração do rastreamento (ou seja, o tempo de carregamento medido).
- Você também pode visualizar os dados de desempenho do rastreamento de tela personalizado.
- Volte para a guia principal do Painel , role para baixo até a tabela de rastreamentos e clique na guia Renderização de tela . Nesta tabela, você verá os rastreamentos de tela personalizados que adicionamos anteriormente, além de quaisquer rastreamentos de tela prontos para uso , como o rastreamento
MainActivity
. - Encontre seu rastreamento de tela personalizado,
MainActivity-TestFragment
. Clique no nome do rastreamento para visualizar os dados agregados de renderização lenta e quadros congelados.
10. Parabéns
Parabéns! Você mediu com sucesso o tempo de carregamento e o desempenho de renderização de tela de uma atividade e um fragmento usando o Firebase Performance Monitoring!
O que você realizou
- Você integrou o Firebase Performance Monitoring em um aplicativo de exemplo
- Agora você entende o ciclo de vida do carregamento do View
- Você mediu o tempo de carregamento de uma atividade e de um fragmento adicionando rastreamentos de código personalizados
- Você gravou quadros lentos/congelados adicionando rastreamentos de tela personalizados com métricas personalizadas
Qual é o próximo
O desempenho do Firebase oferece mais formas de medir o desempenho do seu aplicativo além do rastreamento personalizado. Ele mede automaticamente o tempo de inicialização do aplicativo, os dados de desempenho do aplicativo em primeiro plano e do aplicativo em segundo plano . Chegou a hora de você verificar essas métricas no Firebase Console .
Além disso, o Firebase Performance oferece monitoramento automático de solicitações de rede HTTP/S . Com isso você pode instrumentar facilmente solicitações de rede sem escrever uma única linha de código. Você pode tentar enviar algumas solicitações de rede do seu aplicativo e encontrar as métricas no console do Firebase ?
Bônus
Agora que você sabe como medir o tempo de carregamento e o desempenho de renderização de tela de sua atividade/fragmento usando rastreamentos de código personalizados, explore nossa base de código de código aberto para ver se consegue capturar essas métricas imediatamente para qualquer atividade/fragmento isso faz parte do aplicativo? Sinta-se à vontade para enviar o PR se desejar :-)
11. Aprendizado bônus
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.