Medindo performance e latência com a Navigation Timing API

Performance e latência são alguns dos requisitos de qualidade e experiência do usuário mais desafiadores em desenvolvimento web, especialmente quanto à performance client-side .Sabemos como aplicar técnicas que melhoram muito a performance da página, mas medir o desempenho adequadamente já não é tão trivial à nossa rotina de desenvolvimento. Pensando nisso, o W3C tem uma nova

Performance e latência são alguns dos requisitos de qualidade e experiência do usuário mais desafiadores em desenvolvimento web, especialmente quanto à performance client-side.Sabemos como aplicar técnicas que melhoram muito a performance da página, mas medir o desempenho adequadamente já não é tão trivial à nossa rotina de desenvolvimento. Pensando nisso, o W3C tem uma nova recomendação chamada Navigation Timing API. Com isso, é possível obter métricas e estatísticas detalhadas de modo nativo sobre tempo de carregamento, navegação entre páginas e carregamento de eventos.

A vantagem desta API sobre ferramentas externas e outras técnicas de aferição de latência via JavaScript é a quantidade de informações que podem ser obtidas sobre o tempo de carregamento da página em diferentes fases, proporcionando a medição em um escopo maior (end-to-end). Ferramentas como o PageSpeed e o WebPageTest já têm utilizado dados da Navigation Timing API na análise de carregamento de páginas.

Suporte

Até o momento da escrita deste artigo, a Navigation Timing é suportada pelo Chrome 24.0+, Firefox 18.0+ e IE 9+. A especificação já é recomendação do W3C desde dezembro de 2012 e a versão 2 da API já está em desenvolvimento.

Utilizando o objeto window.performance

Os parâmetros de carregamento da página são acessados através das propriedades navigation e timing do objeto [window.]performance. A propriedade navigation contém informações sobre como o usuário chegou à página e a propriedade timing apresenta as informações sobre carregamento da página.

É possível testar o window.performance diretamente no console do navegador. Supondo que estamos utilizando o Chrome, basta abrir a Developer Tools > Console e digitar performance no prompt. Abaixo, um exemplo do que você poderá obter. Note que o Chrome adiciona mais uma propriedade chamada memory, que pode ser acessada pelo performance.memory, apresentando informações sobre a utilização de memória pelo JavaScript.

Cada uma destas propriedades do timing expressa o tempo de um determinado evento em milisegundos a partir das 00:00 do dia 1º de Janeiro de 1970 (UTC). Quando o valor de algum dos atributos é zero, significa que este evento não ocorreu.

Os tipos de navegação ou “como cheguei até esta página?”

A window.performance.navigation armazena dois atributos que pode ser utilizados para detectar como o usuário chegou à página atual, por exemplo, via um redirecionamento, botões de navegação do histórico do navegador ou entrada normal por URL na barra de endereço. Os atributos são:

  • redirectCount****: o número de redirecionamentos que ocorreram até que a página final fosse carregada;
  • type****: a forma como o usuário chegou à página.

O atributo type é uma constante do tipo enumerada e pode apresentar os seguintes valores:


  Valor



  Descrição





  Navegação iniciada por click em um link, entrada de URL na barra de endereço do navegador, submissão de formulário ou por uma operação de script.


  1



  Recarregamento de página (por botão de refresh ou location.reload()).


  2



  Navegação através dos botões de avançar/voltar do navegador ou por operações de navegação no histórico através de script (ex.: history.back()).


  255



  Qualquer tipo de navegação que não se enquadre nos valores acima.

Os atributos de tempo de carregamento

A propriedade window.performance.timing armazena os dados relevantes sobre o tempo de carregamento desde o momento em que o navegador dispara a requisição para obter a página até o momento em que o carregamento de todo o documento é finalizado. A tabela abaixo mostra uma breve descrição destes eventos na ordem em que eles ocorrem:


  Atributo



  Descrição


  navigationStart



  Tempo depois de o documento anterior ter iniciado o evento de unload.


  Tempo imediatamente antes do evento de unload ser disparado.


  Tempo após o documento anterior ter completado o unload, ou seja, ter sido descarregado para que o próximo documento seja carregado.


  Tempo da busca que iniciou o redirecionamento.


  Tempo após a ocorrência do último redirecionamento.


  Tempo em que o recurso começa a ser buscado.


  Tempo imediatamente antes de iniciar a resolução de nome do domínio.


  Tempo após finalizar a resolução de nome do domínio.


  Tempo imediatamente antes de iniciar a conexão com o servidor para solicitar o recurso.


  Tempo em que a conexão com o servidor é finalizada.


  Para os browsers onde este atributo existe (o IE não o possui no momento), ele retorna o tempo em que foi iniciada uma conexão HTTPS.


  requestStart



  Tempo imediatamente antes da requisição do documento ao servidor.


  Tempo imediatamente após o recebimento do primeiro byte de resposta do servidor.


  Tempo após a finalização da resposta (recebimento do último byte) ou conexão com o servidor.


  domLoading



  Tempo em que o status do documento passa a ser “loading”.


  Tempo em que o status do documento passa a ser “interactive” (DOM completamente interpretado pelo parser do user agent).


  Tempo em que o evento DOMContentLoaded é disparado no documento.


  Tempo após finalizar o evento DOMContentLoaded.


  Tempo em que o status do documento passa a ser “complete”. O status “complete” difere do “interactive” pois engloba a execução de scripts.


  Tempo em que inicia a execução do evento de load da página.


  Tempo em que finaliza a execução do evento de load da página.

Conforme a developer Kasia explica em um artigo de seu blog, os eventos de Rede envolvem tudo que acontecem antes do browser enviar a requisição do documento e pode ajudar a medir latência de rede; os eventos de Servidor são referentes aos tempos de requisição e resposta do documento, ajudando a medir quanto tempo o servidor leva para processar a página; por fim, os eventos do Browser ocorrem a partir do momento que o documento é criado até o momento em que o evento de onload é disparado, auxiliando a medir de fato a performance client-side.

Na timeline abaixo, retirada da documentação da API, é possível ver o fluxo de execução destes eventos.****

Depois de toda esta fundamentação teórica, chegamos de fato no ponto que nos interessa, o pulo do gato: como utilizar estes dados para obter as métricas de performance. Geralmente, a forma de obter estas informações se dá pelo cálculo da diferença entre alguns atributos.

Compilando alguns exemplos apresentados pelo Sam Dutton do HTML5Rocks, Colin Ihrig do SitePoint e a documentação de JS da Mozilla, temos as seguintes combinações (mas é possível obter muito mais):


  Cálculo


  responseEnd – fetchStart


  loadEventEnd – responseEnd


  loadEventEnd – navigationStart


  responseEnd – requestStart


  redirectEnd – redirectStart


  domainLookupEnd – domainLookupStart


  connectEnd – connectStart

Acrescento também alguns testes que fiz com outros cálculos:


  Cálculo


  domInteractive – domLoading


  domComplete – domLoading


  loadEventEnd – loadEventStart

Exemplos

No site Web Timing Demo é possível ter uma prévia de como estes dados podem ser visualizados graficamente. Além disso, a aplicação mostra o valor de todas as propriedades da window.performance para aquela página.

Outra aplicação mais completa é o bookmarket desenvolvido pela Kasia, citada anteriormente neste artigo. Basta arrastá-lo para a barra de favoritos do browser e clicar nele em qualquer página que deseja analisar.

Referências e mais recursos

Can I Use… Navigation Timing API. Disponível em: https://caniuse.com/#feat=nav-timing

Colin Ihrig. Profiling Page Loads with the Navigation Timing API. Disponível em: https://www.sitepoint.com/profiling-page-loads-with-the-navigation-timing-api/

Internet Explorer Developer Center. Navigation timing (Windows). Disponível em: https://msdn.microsoft.com/en-us/library/ie/hh673552(v=vs.85).aspx

Kasia Drzyzga. Breaking Down OnLoad Event – Performance Bookmarklet. Disponível em: https://66.7percentangel.com/2011/12/breaking-down-onload-event-performance-bookmarklet/

Leigh Shevchik. It’s All in the Timing: How to Use the Navigation Timing Specification to Improve Web Performance. Disponível em: https://blog.newrelic.com/2012/05/16/its-all-in-the-timing-how-to-use-the-navigation-timing-specification-to-improve-web-performance/

Microsoft MSDN. performanceTiming object. Disponível em: https://msdn.microsoft.com/en-us/library/ff975075

Mozilla Developer Network. Navigation Timing. Disponível em: https://developer.mozilla.org/en-US/docs/Navigation_timing

Sam Dutton. Measuring Page Load Speed with Navigation Timing. Disponível em: https://www.html5rocks.com/en/tutorials/webperformance/basics/

W3C. HTML5: A vocabulary and associated APIs for HTML and XHTML. Disponível em: https://www.w3.org/TR/html5/syntax.html

W3C. Navigation Timing. Disponível em: https://www.w3.org/TR/navigation-timing/

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *