Introduzindo o React Profiler
React 16.5 adiciona suporte para o novo plugin de profile do DevTools. Este plugin usa a API experimental de profile do React para coletar informações temporais sobre cada componente que é renderizado a fim de identificar gargálos de desempenho em aplicações React. Ele será completamente compatível com nossas futuras funcionalidades de time slicing e suspense.
Este blog post cobre os seguintes tópicos:
Analisando uma aplicação
DevTools irá exibir uma aba chamada “Profiler” para aplicações que suportem a nova API de profiling:
Nota:
react-dom
16.5+ suporta análise no modo DEV. Um pacote de produção para análise está disponível comoreact-dom/profiling
. Leia mais sobre como usar este bundle em fb.me/react-profiling
O painel de “Profiler” estará vazio inicialmente. Clique no botão de gravar para iniciar a análise:
Uma vez que você começou a gravar, DevTools irá coletar automativamente informações de desempenho cada vez que sua aplicação renderizar. Use sua aplicação como você normalente faria. Quando você finalizar a análise, clique no botão de “Parar”.
Assumindo que sua aplicação renderizou pelo menos uma vez enquanto a análise acontecia, DevTools irá mostrar diversas formas para ver os dados de desempenho. Iremos olhar cada uma destas formas abaixo.
Lendo dados de desempenho
Navegando por commits
Conceitualmente, React funciona em duas fases:
- A fase de render determina quais mudanças precisam ser feitas no DOM, por exemplo. Durante esta fase, React executa
render
e então compara o resultado com o render anterior. - A fase de commit aplica todas as mudanças. (No caso do React DOM, é quando o React insere, atualiza e remove nós do DOM.) O React também executa os métodos do ciclo de vida como
componentDidMount
ecomponentDidUpdate
durante esta fase.
O profiler do DevTools agrupa a informação de desempenho por commit. Commits são exibidos em um gráfico de barra próximo ao topo do profiler:
Cada barra no gráfico representa um único commit com o commit atualmente selecionado pintado de preto. Você pode clicar numa barra (ou nas setas para esquerda/direita) para selecionar um commit diferente.
A cor e a altura de cada barra corresponde ao tempo que aquele commit demorou para renderizar. (Barras amarelas altas demoraram mais do que as barras azuis menores.)
Filtrando commits
O quanto mais você executar o profile, mais vezes a sua aplicação irá renderizar. Em alguns casos você vai acabar com commits demais para analisar facilmente. O profiler oferece um mecanismo de filtro para ajudar nestes casos. Use-o para especificar um limit e o profiler irá esconder todos os commits que foram mais rápidos que aquele valor.
Gráfico de chama
A visualização de gráfico de chama (flame chart) representa o estado da sua aplicação para um commit particular.
Cada barra no gráfico representa um componente React (por exemplo App
, Nav
).
O tamanho e cor da barra representa quanto tempo o componente e seus filhos demoraram para renderizar.
(A largura da barra representa quanto tempo foi gasto quando o componente foi renderizado pela última vez e a cor representa quanto tempo foi gasto como parte do commit atual.)
Nota:
A largura da barra indica quanto tempo demorou para renderizar o componente (e seus filhos) na última vez que foi renderizado. Se o componente não re-renderizou como parte do último commit, o tempo representa uma renderização anterior. O quanto maior for um componente, mais demorado é para ele renderizar.
A cor da barra indica quanto tempo o componente (e seus filhos) demoraram para renderizar no commit selecionado. Componentes amarelos levaram mais tempo, componentes azuis levaram menos tempo e componentes cinza não renderizaram durante este commit.
Por exemplo, o commit acima levou um total de 18.4ms para renderizar.
O componente Router
foi o “mais caro” para renderizar (levando 18.4ms).
A maior parte deste tempo foi devido a seus filhos, Nav
(8.4ms) e Route
(7.9ms).
O resto do tempo se dividiu entre seus filhos remanescentes ou gasto no método de render do próprio componente.
Você pode aumentar ou diminuir o zoom no gráfico de chama clicando nos componentes:
Clicar num componente irá selecioná-lo e mostrar, no painel lateral direito, informações que incluem suas props
e estado
no momento deste commit.
Você pode analisar e aprender mais sobre como o componente realmente renderizou durante o commit:
Em alguns casos, selecionar um componente e alternar entre commits pode dar uma dica do porquê o componente renderizou:
A imagem acima mostra que state.scrollOffset
mudou entre os commits.
Foi isto que provavelmente causou que o componente List
renderizasse novamente.
Gráfico de classificação
A visualização de gráfico de classificação (ranked chart) representa um único commit.
Cada barra no gráfico representa um componente React (por exemplo App
, Nav
).
O gráfico é ordenado de tal forma que o componente que demorou mais para renderizar fica no topo.
Nota:
O tempo de renderização de um componente inclui o tempo gasto para renderizar seus filhos, portanto, os componentes que demoram mais para renderizar estão geralmente próximos ao topo da árvore.
Assim como no gráfico de chama, você pode aumentar ou diminuir o zoom de um gráfico de classificação ao clicar nos componentes.
Gráfico de componente
Algumas vezes é útil visualizar quantas vezes um componente específico renderizou enquanto você estava analisando. O gráfico de componente fornece esta informação no formato de um gráfico de barras. Cada barra no gráfico representa uma vez que o componente renderizou. A cor e a altura de cada barra corresponde a quanto tempo o componente demorou para renderizar relativamente a outros componentes num commit específico.
O gráfico acima mostra que o componente List
renderizou 11 vezes.
Ele também mostra que cada vez que ele renderizou, foi o componente mais “caro” no commit (significando que foi o mais demorado).
Para visualizar este gráfico, você deve clicar duas vezes num componente ou selecionar um componente e clicar no ícone com um gráfico de barras azul no painel de detalhe a direita. Você pode retornar ao gráfico anterior clicando no botão “x” no painel de detalhe a direita. Você também pode clicar duas vezes numa barra específica para visualizar mais informações sobre aquele commit.
Se o componente selecionado não renderizou durante uma sessão de análise, a seguinte mensagem irá ser exibida:
Interações
React recentemente adicionou outra API experimental para rastrear a causa de uma atualização. “Interações” rastreadas com esta API irão ser mostradas no profiler:
A imagem acima mostra uma sessão de análise que registrou quatro interações. Cada linha representa uma interação que foi rastreada. Os pontos coloridos através da linha representam commits relacionados àquela interação.
Você também pode ver quais interações foram rastreadas para um commit específico a partir das visualizações de gráfico de chama e de gráfico de classificação:
Você pode navigar através de interações e commits clicando neles:
A API de rastreamento ainda é novo e iremos abordar ela com mais detalhes em posts futuros.
Guia de soluções de problemas
Nenhum dado de profile foi salvo para a raiz selecionada
Se sua aplicação possui múltiplas “raizes”, você talvez veja a seguinte mensagem após a análise:
Esta mensagem indica que nenhum dado de dessempenho foi gravado para a raiz que está selecionada no painel de “Elementos”. Neste caso, tente selecionar uma raiz diferente no painel para visualizar informações analisadas para aquela raiz:
Nenhum dado de tempo a ser exibido para o commit selecionado
Às vezes, um commit pode ser tão rápido que perfomance.now()
não retorna nenhuma informação de tempo significativa para o DevTools.
Neste caso, a seguinte mensagem irá aparecer:
Vídeo aprofundado
O vídeo a seguir demonstra como o React profiler pode ser usado para detectar e melhorar gargálos de performance numa aplicação React real.