Depurar o desempenho no campo

Aprenda a atribuir seus dados de performance com informações de depuração para identificar e corrigir problemas de usuários reais com análises

O Google oferece duas categorias de ferramentas para medir e depurar o desempenho:

  • Ferramentas de laboratório:ferramentas como o Lighthouse, em que a página é carregada em um ambiente simulado que pode imitar várias condições (por exemplo, uma rede lenta e um dispositivo móvel de baixo custo).
  • Ferramentas de campo:ferramentas como o Relatório de experiência do usuário do Chrome (CrUX, na sigla em inglês), que é baseado em dados agregados e reais do usuário do Chrome. Os dados de campo informados por ferramentas como o PageSpeed Insights e o Search Console são provenientes de dados do CrUX.

Embora as ferramentas de campo ofereçam dados mais precisos, que representam o que os usuários reais vivenciam, as ferramentas de laboratório geralmente ajudam mais a identificar e corrigir problemas.

Os dados do CrUX são mais representativos do desempenho real da sua página, mas conhecer as pontuações do CrUX provavelmente não vai ajudar você a descobrir como melhorar o desempenho.

O Lighthouse, por outro lado, identifica problemas e faz sugestões específicas de como melhorar. No entanto, o Lighthouse só vai fazer sugestões para problemas de desempenho descobertos no momento do carregamento da página. Ele não detecta problemas que só aparecem como resultado da interação do usuário, como rolar ou clicar nos botões da página.

Isso levanta uma questão importante: como capturar informações de depuração das Core Web Vitals ou de outras métricas de performance de usuários reais no campo?

Esta postagem explica em detalhes quais APIs você pode usar para coletar mais informações de depuração para cada uma das métricas atuais das Core Web Vitals e oferece ideias sobre como capturar esses dados na sua ferramenta de análise atual.

APIs para atribuição e depuração

Cumulative Layout Shift (CLS)

De todas as métricas das Core Web Vitals, a CLS talvez seja a que reúne as informações de depuração mais importantes. O CLS é medido durante toda a vida útil da página. Portanto, a forma como um usuário interage com a página (como rolar a página, clicar em um link etc.) pode ter um impacto significativo em saber se há mudanças de layout e quais elementos estão mudando.

Considere o seguinte relatório do PageSpeed Insights:

Um relatório do PageSpeed Insights com diferentes valores de CLS
Os PageSpeed Insights mostram dados de campo e de laboratório, quando disponíveis, e eles podem ser diferentes

O valor informado para CLS do laboratório (Lighthouse) em comparação com o CLS do campo (dados do CrUX) é bastante diferente, e isso faz sentido se você considerar que a página pode ter muito conteúdo interativo que não está sendo usado quando testado no Lighthouse.

No entanto, mesmo que você entenda que a interação do usuário afeta os dados de campo, ainda é necessário saber quais elementos na página estão mudando para resultar em uma pontuação de 0,28 na 75ª percentila. A interface LayoutShiftAttribution permite isso.

Receber atribuição de mudança de layout

A interface LayoutShiftAttribution é exposta em cada entrada layout-shift que a API Layout Instability emite.

Para uma explicação detalhada dessas duas interfaces, consulte Mudanças de layout de depuração. Para os fins desta postagem, a principal coisa que você precisa saber é que, como desenvolvedor, você pode observar todas as mudanças de layout que ocorrem na página, bem como quais elementos estão mudando.

Confira um exemplo de código que registra cada mudança de layout e os elementos que foram alterados:

new PerformanceObserver((list) => {
 
for (const {value, startTime, sources} of list.getEntries()) {
   
// Log the shift amount and other entry info.
    console
.log('Layout shift:', {value, startTime});
   
if (sources) {
     
for (const {node, curRect, prevRect} of sources) {
       
// Log the elements that shifted.
        console
.log('  Shift source:', node, {curRect, prevRect});
     
}
   
}
 
}
}).observe({type: 'layout-shift', buffered: true});

Provavelmente não é prático medir e enviar dados para a ferramenta de análise para cada mudança de layout que ocorre. No entanto, monitorando todas as mudanças, você pode acompanhar as piores e informar apenas sobre elas.

O objetivo não é identificar e corrigir todas as mudanças de layout que ocorrem para todos os usuários. O objetivo é identificar as mudanças que afetam o maior número de usuários e, portanto, contribuem mais para a CLS da página na 75ª percentil.

Além disso, não é necessário calcular o maior elemento de origem sempre que houver uma mudança. Você só precisa fazer isso quando estiver pronto para enviar o valor da CLS à ferramenta de análise.

O código a seguir usa uma lista de entradas layout-shift que contribuíram para a CLS e retorna o maior elemento de origem da maior mudança:

function getCLSDebugTarget(entries) {
 
const largestEntry = entries.reduce((a, b) => {
   
return a && a.value > b.value ? a : b;
 
});
 
if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
   
const largestSource = largestEntry.sources.reduce((a, b) => {
     
return a.node && a.previousRect.width * a.previousRect.height >
          b
.previousRect.width * b.previousRect.height ? a : b;
   
});
   
if (largestSource) {
     
return largestSource.node;
   
}
 
}
}

Depois de identificar o maior elemento que contribui para a maior mudança, você pode informar isso à sua ferramenta de análise.

O elemento que contribui mais para a CLS de uma determinada página provavelmente vai variar de usuário para usuário, mas, se você agregar esses elementos em todos os usuários, vai ser possível gerar uma lista de elementos variáveis que afetam o maior número de usuários.

Depois de identificar e corrigir a causa raiz das mudanças desses elementos, o código de análise vai começar a informar mudanças menores como as "piores" nas suas páginas. Eventualmente, todas as mudanças informadas serão pequenas o suficiente para que suas páginas estejam dentro do limite "bom" de 0,1.

Alguns outros metadados que podem ser úteis para capturar junto com o maior elemento de origem da mudança são:

  • O horário do maior turno
  • O caminho do URL no momento da maior mudança (para sites que atualizam dinamicamente o URL, como aplicativos de página única).

Maior exibição de conteúdo (LCP)

Para depurar a LCP no campo, as informações principais necessárias são qual elemento específico foi o maior (o elemento candidato da LCP) para aquele carregamento de página específico.

É possível, e até comum, que o elemento candidato do LCP seja diferente de usuário para usuário, mesmo na mesma página.

Esse problema pode ocorrer por vários motivos:

  • Os dispositivos dos usuários têm resoluções de tela diferentes, o que resulta em layouts de página diferentes e, portanto, em elementos diferentes visíveis na janela de visualização.
  • Os usuários nem sempre carregam as páginas roladas até o topo. Muitas vezes, os links contêm identificadores de fragmento ou até fragmentos de texto, o que significa que é possível carregar e mostrar as páginas em qualquer posição de rolagem.
  • O conteúdo pode ser personalizado para o usuário atual, portanto, o elemento candidato do LCP pode variar muito de usuário para usuário.

Isso significa que você não pode fazer suposições sobre qual elemento ou conjunto de elementos será o candidato de LCP mais comum para uma página específica. É necessário medir com base no comportamento de usuários reais.

Identificar o elemento candidato do LCP

Para determinar o elemento candidato do LCP em JavaScript, use a API Largest Contentful Paint, a mesma API usada para determinar o valor de tempo do LCP.

Ao observar as entradas largest-contentful-paint, é possível determinar o elemento candidato atual do LCP analisando a propriedade element da última entrada:

new PerformanceObserver((list) => {
 
const entries = list.getEntries();
 
const lastEntry = entries[entries.length - 1];

  console
.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});

Depois de saber qual é o elemento candidato do LCP, você pode enviá-lo para sua ferramenta de análise com o valor da métrica. Assim como na CLS, isso vai ajudar a identificar quais elementos são mais importantes para otimizar primeiro.

Além do elemento candidato do LCP, também pode ser útil medir os tempos das subpartes do LCP, que podem ser úteis para determinar quais etapas de otimização específicas são relevantes para seu site.

Interaction to Next Paint (INP)

Os dados mais importantes a serem coletados no campo para INP são:

  1. Qual elemento recebeu a interação
  2. Por que tipo de interação foi
  3. Quando a interação ocorreu

Uma das principais causas de interações lentas é uma linha de execução principal bloqueada, o que pode ser comum enquanto o JavaScript está sendo carregado. Saber se a maioria das interações lentas ocorre durante o carregamento da página é útil para determinar o que precisa ser feito para corrigir o problema.

A métrica INP considera a latência total de uma interação, incluindo o tempo necessário para executar todos os listeners de eventos registrados, bem como o tempo necessário para pintar o próximo frame depois que todos os listeners de eventos foram executados. Isso significa que, para a INP, é muito útil saber quais elementos alvo tendem a resultar em interações lentas e quais tipos de interações são essas.

O código a seguir registra o elemento de destino e o horário da entrada do INP.

function logINPDebugInfo(inpEntry) {
  console
.log('INP target element:', inpEntry.target);
  console
.log('INP interaction type:', inpEntry.name);
  console
.log('INP time:', inpEntry.startTime);
}

Esse código não mostra como determinar qual entrada event é a entrada INP, porque essa lógica é mais complexa. No entanto, a seção a seguir explica como conseguir essas informações usando a biblioteca JavaScript web-vitals.

Uso com a biblioteca JavaScript do Web Vitals

As seções anteriores oferecem algumas sugestões gerais e exemplos de código para capturar informações de depuração para incluir nos dados enviados à ferramenta de análise.

Desde a versão 3, a biblioteca JavaScript web-vitals inclui um build de atribuição que mostra todas essas informações e alguns sinais adicionais.

O exemplo de código a seguir mostra como definir um parâmetro de evento (ou dimensão personalizada) adicional contendo uma string de depuração útil para ajudar a identificar a causa raiz dos problemas de performance.

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
 
const eventParams = {
    metric_value
: value,
    metric_id
: id,
 
}

 
switch (name) {
   
case 'CLS':
      eventParams
.debug_target = attribution.largestShiftTarget;
     
break;
   
case 'LCP':
      eventParams
.debug_target = attribution.element;
     
break;
   
case 'INP':
      eventParams
.debug_target = attribution.interactionTarget;
     
break;
 
}

 
// Assumes the global `gtag()` function exists, see:
 
// https://developers.google.com/analytics/devguides/collection/ga4
  gtag
('event', name, eventParams);
}

onCLS
(sendToGoogleAnalytics);
onLCP
(sendToGoogleAnalytics);
onINP
(sendToGoogleAnalytics);

Esse código é específico do Google Analytics, mas a ideia geral também se aplica a outras ferramentas de análise.

Esse código também mostra como gerar relatórios sobre um único indicador de depuração, mas é útil para coletar e gerar relatórios sobre vários indicadores diferentes por métrica.

Por exemplo, para depurar o INP, é recomendável coletar o elemento com o qual está sendo interagido, o tipo de interação, o tempo, o loadState, as fases de interação e muito mais, como dados de frame de animação longa.

O build de atribuição web-vitals expõe outras informações de atribuição, conforme mostrado no exemplo a seguir para INP:

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
 
const eventParams = {
    metric_value
: value,
    metric_id
: id,
 
}

 
switch (name) {
   
case 'INP':
      eventParams
.debug_target = attribution.interactionTarget;
      eventParams
.debug_type = attribution.interactionType;
      eventParams
.debug_time = attribution.interactionTime;
      eventParams
.debug_load_state = attribution.loadState;
      eventParams
.debug_interaction_delay = Math.round(attribution.inputDelay);
      eventParams
.debug_processing_duration = Math.round(attribution.processingDuration);
      eventParams
.debug_presentation_delay =  Math.round(attribution.presentationDelay);
     
break;

   
// Additional metric logic...
 
}

 
// Assumes the global `gtag()` function exists, see:
 
// https://developers.google.com/analytics/devguides/collection/ga4
  gtag
('event', name, eventParams);
}

onCLS
(sendToGoogleAnalytics);
onLCP
(sendToGoogleAnalytics);
onINP
(sendToGoogleAnalytics);

Consulte a documentação de atribuição de web vitals para conferir a lista completa de sinais de depuração expostos.

Gerar relatórios e visualizar os dados

Depois de começar a coletar informações de depuração com os valores das métricas, a próxima etapa é agregar os dados de todos os usuários para começar a procurar padrões e tendências.

Como mencionado anteriormente, você não precisa necessariamente resolver todos os problemas que seus usuários estão enfrentando. Em vez disso, você quer resolver, principalmente no início, os problemas que estão afetando o maior número de usuários, que também são os que têm o maior impacto negativo nas suas pontuações do Core Web Vitals.

Para o GA4, consulte o artigo dedicado sobre como consultar e visualizar os dados usando o BigQuery.

Resumo

Esperamos que esta postagem tenha ajudado a descrever as maneiras específicas de usar as APIs de performance atuais e a biblioteca web-vitals para receber informações de depuração e ajudar a diagnosticar a performance com base nas visitas de usuários reais no campo. Embora este guia se concentre nas Core Web Vitals, os conceitos também se aplicam à depuração de qualquer métrica de performance mensurável em JavaScript.

Se você está começando a medir a performance e já é usuário do Google Analytics, a ferramenta de relatório das Core Web Vitals pode ser um bom lugar para começar, porque ela já oferece suporte para informações de depuração das métricas das Core Web Vitals.

Se você é um fornecedor de análise e quer melhorar seus produtos e fornecer mais informações de depuração aos usuários, considere algumas das técnicas descritas aqui, mas não se limite apenas às ideias apresentadas aqui. Esta postagem é aplicável a todas as ferramentas de análise. No entanto, ferramentas de análise individuais provavelmente podem (e devem) capturar e informar ainda mais informações de depuração.

Por fim, se você achar que há lacunas na sua capacidade de depurar essas métricas devido à falta de recursos ou informações nas próprias APIs, envie seu feedback para web-vitals-feedback@googlegroups.com.