Depurar o desempenho no campo

Saiba como atribuir seus dados de desempenho com informações de depuração para identificar e corrigir problemas reais dos usuários com o Analytics.

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, dados que na verdade representam a experiência dos usuários reais, as ferramentas de laboratório geralmente são melhores para identificar e corrigir problemas.

Os dados do CrUX representam melhor o desempenho real da página, mas saber as pontuações do CrUX provavelmente não 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ó fará sugestões para problemas de desempenho detectados no tempo de 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 é possível capturar informações de depuração para as Core Web Vitals ou outras métricas de desempenho de usuários reais em 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. A CLS é medida ao longo de toda a vida útil da página. Portanto, a maneira como o usuário interage com a página (a distância rolada, o que clica e assim por diante) pode ter um impacto significativo na possibilidade de mudanças no layout e nos elementos.

Considere o seguinte relatório do PageSpeed Insights:

Um relatório do PageSpeed Insights com diferentes valores de CLS
O PageSpeed Insights mostra dados de campo e de laboratório quando disponíveis, que podem ser diferentes

O valor informado para a CLS do laboratório (Lighthouse) em comparação com o CLS de campo (dados CrUX) é muito diferente. 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 torna isso possível.

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 sobre as duas interfaces, consulte Depurar mudanças de layout. Para os fins desta postagem, o principal ponto que você precisa saber é que, como desenvolvedor, você pode observar cada mudança de layout que acontece 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 cada mudança de layout que ocorre para cada usuário. A meta é identificar as mudanças que afetam o maior número de usuários e, assim, contribuem mais para a CLS da página no 75o 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 mais contribui para a CLS em uma determinada página provavelmente varia de usuário para usuário. No entanto, se você agregar esses elementos em todos os usuários, poderá gerar uma lista de elementos em constante mudança que afetam a maior parte do número de usuários.

Depois de identificar e corrigir a causa raiz das mudanças desses elementos, o código do Google Analytics vai começar a informar mudanças menores como as "piores" mudanças nas suas páginas. Eventualmente, todas as mudanças informadas serão pequenas o suficiente para que suas páginas estejam bem 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 da maior variação
  • 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 quais elementos foram os maiores (o elemento candidato da LCP) para aquele carregamento de página específico.

É completamente possível (na verdade, muito comum) que o elemento candidato à LCP seja diferente de usuário para usuário, mesmo para exatamente a 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 variados e, assim, elementos distintos ficam visíveis na janela de visualização.
  • Os usuários nem sempre carregam 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 à 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. Você precisa medi-lo com base no comportamento do usuário real.

Identifique o elemento candidato à 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 conhecer o elemento candidato à LCP, envie-o para sua ferramenta de análise com o valor da métrica. Assim como na CLS, isso ajudará a identificar quais elementos são mais importantes de otimizar primeiro.

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

Interação com a próxima exibição (INP)

As informações mais importantes a serem capturadas no campo para a INP são:

  1. Com qual elemento houve uma interação
  2. Por que o tipo de interação
  3. Quando essa 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 de destino tendem a resultar em interações lentas e que tipos de interações são.

O código a seguir registra o elemento de destino e a hora da entrada INP.

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

Observe que esse código não mostra como determinar qual entrada event é a entrada INP, já que essa lógica está mais envolvida. No entanto, a seção a seguir explica como conseguir essas informações usando a biblioteca JavaScript web-vitals.

Uso com a biblioteca JavaScript web-vitals

As seções anteriores oferecem algumas sugestões gerais e exemplos de código para capturar informações de depuração a serem incluídas 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 para o Google Analytics, mas a ideia geral também deve ser aplicada 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 abaixo 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, não é necessário resolver todos os problemas que os usuários estão enfrentando. Você precisa resolver, especialmente no começo, os problemas que afetam o maior número de usuários e aqueles que têm o maior impacto negativo nas suas pontuações das Core Web Vitals.

Para o GA4, consulte o artigo dedicado sobre como consultar e visualizar 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 seja focado nas Core Web Vitals, os conceitos também se aplicam à depuração de qualquer métrica de desempenho mensurável em JavaScript.

Se você está começando a avaliar a performance e já é um usuário do Google Analytics, a ferramenta Relatório de Métricas da Web é um bom ponto de partida, porque ela já oferece suporte a informações de depuração de relatórios para as Core Web Vitals.

Se você é um fornecedor de análises e quer melhorar seus produtos e fornecer mais informações de depuração aos usuários, use 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 à ausência de recursos ou informações nas próprias APIs, envie seu feedback para web-vitals-feedback@googlegroups.com.