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 do 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 simples).
  • Ferramentas de campo:ferramentas como o Chrome User Experience Report (CrUX, na sigla em inglês), que se baseia em dados agregados de usuários reais do Chrome. Os dados de campo informados por ferramentas como PageSpeed Insights e 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. No entanto, saber as pontuações do CrUX não ajudará você a descobrir como melhorar o desempenho.

O Lighthouse, por outro lado, vai identificar problemas e fazer sugestões específicas de melhorias. 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 se manifestam apenas como resultado da interação do usuário, como rolagem ou clique em botões na 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 Core Web Vitals atuais e dará ideias de 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 Core Web Vitals, a CLS talvez seja a mais importante para coletar informações de depuração no campo. 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 precisará saber quais elementos da página estão mudando para resultar em uma pontuação de 0,28 no 75o percentil. A interface LayoutShiftAttribution torna isso possível.

Receber atribuição de troca 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, bem como os elementos que mudaram:

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 à sua ferramenta de análise para cada mudança de layout que ocorrer. No entanto, ao monitorar todas as mudanças, você pode acompanhar as piores e relatar apenas informações 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, você não precisa computar o maior elemento de origem sempre que houver uma mudança, só precisa fazer isso quando estiver pronto para enviar o valor de CLS para sua 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, informe-o à sua ferramenta de análise.

O elemento que mais contribui para a CLS em uma determinada página provavelmente variará de usuário para usuário, mas se você agregar esses elementos em todos os usuários, poderá gerar uma lista de elementos em mudança que afetam a maior parte do número de usuários.

Depois de identificar e corrigir a causa raiz das mudanças para esses elementos, seu código de análise vai começar a informar mudanças menores à medida que as "piores" mudanças acontecerem 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 de 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 em campo, a principal informação necessária é qual elemento específico foi o maior elemento (o candidato à LCP) para esse 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 fragmentos ou até fragmentos de texto, o que significa que é possível que suas páginas sejam carregadas e exibidas em qualquer posição de rolagem na página.
  • 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 não é possível fazer suposições sobre qual elemento ou conjunto de elementos será o elemento candidato à 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 à LCP no JavaScript, use a API Largest Contentful Paint, a mesma API usada para determinar o valor de tempo da LCP.

Ao observar entradas largest-contentful-paint, é possível determinar o elemento candidato à LCP atual 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 Next Paint (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 qualquer listener de eventos registrado, bem como o tempo necessário para pintar o próximo frame depois que todos os listeners de eventos forem 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 web-vitals JavaScript

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, além de alguns outros indicadores.

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

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);
onFID(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 de vários indicadores diferentes por métrica.

Por exemplo, para depurar o INP, convém coletar o elemento com que está interagindo, o tipo de interação, o tempo, o loadState, as fases de interação e muito mais (como dados de frames de animação longos).

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);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

Consulte a documentação sobre atribuição da web-vitals para conferir a lista completa de indicadores 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, mas é importante resolver, principalmente no início, os problemas que afetam o maior número de usuários e aqueles com maior impacto negativo nas 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 desempenho atuais e a biblioteca web-vitals para acessar informações de depuração e diagnosticar o desempenho com base nas visitas de usuários reais em 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álise 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 se destina a ser aplicável a todas as ferramentas de análise. No entanto, ferramentas de análise individuais provavelmente podem (e precisam) capturar e relatar ainda mais informações de depuração.

Por fim, se você achar que há lacunas na depuração dessas métricas devido à ausência de recursos ou informações nas próprias APIs, envie seu feedback para web-vitals-feedback@googlegroups.com.