Medir navegações probabilísticas

Publicado em: 1º de fevereiro de 2023, última atualização: 2 de setembro de 2026

Browser Support

  • Chrome: 151.
  • Edge: 151.
  • Firefox: not supported.
  • Safari: not supported.

Source

Desde o lançamento, a iniciativa Core Web Vitals busca medir a experiência real do usuário em um site, em vez de detalhes técnicos sobre como ele é criado ou carregado. As três métricas do Core Web Vitals foram criadas como métricas centradas no usuário, uma evolução em relação às métricas técnicas atuais, como DOMContentLoaded ou load, que mediam tempos geralmente não relacionados à percepção dos usuários sobre a performance da página. Por isso, a tecnologia usada para criar o site não deve afetar a pontuação, desde que o site tenha um bom desempenho.

A realidade é sempre um pouco mais complicada do que o ideal, e a arquitetura popular de aplicativo de página única nunca foi totalmente compatível com as métricas Core Web Vitals. Em vez de carregar páginas da Web distintas e individuais enquanto o usuário navega pelo site, esses aplicativos da Web usam as chamadas "navegações suaves", em que o conteúdo da página é alterado por JavaScript. Nesses aplicativos, a ilusão de uma arquitetura de página da Web convencional é mantida alterando o URL e enviando os URLs anteriores no histórico do navegador para permitir que os botões "Voltar" e "Avançar" funcionem como o usuário espera.

Muitos frameworks JavaScript usam esse modelo, mas cada um de uma maneira diferente. Como isso está fora do que o navegador tradicionalmente entende como uma "página", a medição sempre foi difícil: onde está a linha entre uma interação na página atual e considerar isso como uma página nova?

A equipe do Chrome considera esse desafio há algum tempo e está buscando padronizar uma definição do que é uma "navegação suave" e como as Core Web Vitals podem ser medidas para isso, de maneira semelhante à medição de sites implementados na arquitetura convencional de várias páginas (MPA, na sigla em inglês).

Fizemos várias melhorias na proposta com base no feedback dos desenvolvedores e lançamos duas novas APIs de desempenho para ajudar a resolver esse problema no Chrome 151.

O que é uma navegação suave?

Criamos a seguinte definição de navegação suave:

  • A navegação é iniciada por uma ação do usuário.
  • A navegação resulta em uma mudança visível de URL para o usuário.
  • A interação resulta em uma renderização visível.

Para alguns sites, essa definição pode levar a falsos positivos (que os usuários não considerariam uma "navegação") ou falsos negativos (em que o usuário considera que houve uma "navegação", mesmo que não atenda a esses critérios). Queremos saber sua opinião no repositório de especificações de navegação suave.

Suporte do DevTools para navegações suaves

Adicionamos suporte a navegações suaves no painel de desempenho das DevTools na visualização Métricas em tempo real e na visualização de rastreamento com suporte a Insights e marcadores:

Suporte do DevTools para navegações suaves.

Como o Chrome implementa navegações suaves para desenvolvedores da Web?

Depois que o recurso de navegação suave for ativado (mais detalhes na próxima seção), o Chrome vai mudar a forma como informa algumas métricas de performance:

  • Um evento soft-navigation PerformanceTiming será emitido após cada navegação suave detectada.
  • Essa entrada soft-navigation vai incluir um navigationId, o novo URL no atributo name e um interactionId da interação inicial.
  • Uma ou mais entradas interaction-contentful-paint serão emitidas após interações que causam uma renderização significativa de conteúdo. Ele vai conter uma entrada largestContentfulPaint que pode ser usada para medir o Largest Contentful Paint (LCP) em navegações suaves.
  • O atributo navigationId é adicionado a cada um dos tempos de desempenho (first-paint, first-contentful-paint, largest-contentful-paint, interaction-contentful-paint, first-input-delay, event e layout-shift). Isso corresponde à entrada de navegação em que o evento foi emitido. Quando essas entradas abrangem navegações suaves, elas podem conter o navigationId anterior ou seguinte, dependendo de quando a entrada foi emitida. Saiba mais na seção Informar as métricas no URL adequado.
  • O soft-navigation vai incluir uma função getLargestInteractionContentfulPaint() para recuperar a maior entrada interaction-contentful-paint dessa navegação. Isso pode ser usado como o LCP inicial para essa navegação, que pode ser atualizado à medida que mais entradas interaction-contentful-paint para essa interação são observadas. Observação: isso substitui um atributo largestInteractionContentfulPaint disponível em testes de origem anteriores.
  • É possível que algumas entradas de interaction-contentful-paint tenham ocorrido antes da navegação suave (se a atualização do URL não acontecer até depois dessas renderizações). Nesses casos, a função getLargestInteractionContentfulPaint() evita a necessidade de armazenar em buffer e analisar entradas antigas depois que uma navegação suave é concluída. A entrada retornada por getLargestInteractionContentfulPaint() é uma cópia exata da maior entrada de interaction-contentful-paint no momento em que foi emitida. Portanto, essa entrada pode ter usado o navigationId anterior, já que foi quando a renderização ocorreu. No entanto, essas renderizações devem ser medidas em relação ao novo navigationId.
  • A entrada soft-navigation também vai incluir paintTime e presentationTime como o FCP dessa navegação.
  • As entradas interaction-contentful-paint também serão emitidas após outras interações, mas o LCP de um URL deve ser restrito às entradas interaction-contentful-paint que correspondem às navegações suaves interactionId para excluir essas entradas e também apenas às propriedades largestContentfulPaint dentro delas.

Essas mudanças vão permitir que as Core Web Vitals e algumas das métricas de diagnóstico associadas sejam medidas por navegação na página, mas há algumas nuances que precisam ser consideradas.

Quais são as implicações de ativar as navegações suaves no Chrome?

Confira algumas das mudanças que os proprietários de sites precisam considerar depois de ativar esse recurso:

  • O monitoramento das entradas soft-navigation permite "dividir" as entradas de performance em cada "navegação".
  • As métricas CLS e INP já podem ser segmentadas a seu critério, em vez de serem medidas durante todo o ciclo de vida da página. No entanto, o recurso de navegação suave oferece uma medida padronizada de quando isso acontece, independente da tecnologia usada.
  • A entrada largest-contentful-paint é finalizada em uma interação (necessária para iniciar uma navegação suave), então só pode ser usada para medir o LCP da navegação "difícil" inicial. Isso significa que ela não vai mudar quando as navegações suaves forem medidas. Assim, o LCP do carregamento de página inicial e de navegação completa pode ser medido como sempre foi.
  • A nova entrada interaction-contentful-paint emitida pelas interações pode ser usada para medir o LCP em navegações suaves. Para isso, basta analisar a propriedade largestContentfulPaint. No entanto, há algumas considerações sobre como usar essa entrada, que vamos discutir neste artigo.
  • Note que nem todos os usuários vão ter acesso a esse recurso de navegação suave, principalmente aqueles que usam outros navegadores ou versões do Chrome anteriores à 151. Alguns usuários podem não informar métricas baseadas em navegação suave, mesmo que informem métricas de Core Web Vitals.

Verifique com seu provedor de RUM se ele oferece suporte à medição das Core Web Vitals por navegação suave. Muitas pessoas estão planejando testar esse novo padrão e vão levar em consideração as considerações anteriores. Enquanto isso, alguns provedores também permitem medições limitadas de métricas de performance com base nas próprias heurísticas.

Para mais informações sobre como medir as métricas de navegações suaves, consulte a seção "Medir as Core Web Vitals por navegação suave".

Como faço para ativar as navegações suaves no Chrome?

O recurso de navegações suaves é ativado por padrão a partir do Chrome 151.

Recurso que detecta a compatibilidade com a API Soft Navigations

Use o código a seguir para testar se a API é compatível:

if (PerformanceObserver.supportedEntryTypes.includes('soft-navigation')) {
  // Monitor Soft Navigations
}

ou então:

if ('SoftNavigationEntry' in window) {
  // Monitor Soft Navigations
}

Como posso medir navegações suaves?

Quando compatíveis, as métricas podem ser informadas usando a API PerformanceObserver, assim como outras métricas. No entanto, há algumas considerações extras que precisam ser levadas em conta para essas métricas.

Informar navegações suaves

É possível usar um PerformanceObserver para observar navegações suaves. Confira um exemplo de snippet de código que registra entradas de navegação suave no console, incluindo navegações suaves anteriores nesta página usando a opção buffered:

const observer = new PerformanceObserver(console.log);
observer.observe({ type: "soft-navigation", buffered: true });

Isso pode ser usado para finalizar as métricas de página de ciclo de vida completo da navegação anterior.

Gerar relatórios sobre as métricas no URL adequado

Quando uma navegação suave é detectada, as Core Web Vitals da página anterior precisam ser finalizadas e informadas para o URL anterior. Em seguida, um novo monitoramento precisa ser iniciado para o novo URL.

O atributo name da entrada soft-navigation apropriada vai conter o novo URL para informar as métricas, e o navigationId será a referência exclusiva para essa navegação, já que o mesmo URL pode ser visitado várias vezes durante a vida útil de um aplicativo de página única.

Isso precisa ser definido como cada entrada de soft-navigation e usado para informar métricas até que a próxima entrada de soft-navigation seja recebida.

Denunciar o URL correto de interaction-contentful-paint

São necessárias outras considerações para calcular o LCP das entradas interaction-contentful-paint, já que nem todas as entradas interaction-contentful-paint devem ser mapeadas usando o navigationId e informadas como LCP para esse URL:

  • O primeiro problema é que as entradas interaction-contentful-paint podem ser emitidas antes da navegação suave se uma renderização ocorrer antes da atualização do URL. Nesses casos, o navigationId será do URL antigo. Se o URL for atualizado primeiro, a renderização vai concluir a navegação suave. Nesse caso, a entrada soft-navigation será emitida primeiro, e a interaction-contentful-paint terá o novo URL.
  • O segundo problema é que, no interaction-contentful-paint, as entradas vão continuar sendo emitidas para interações mais recentes, já que o escopo dessa métrica de performance vai além do LCP para navegações leves. Queremos considerar apenas as renderizações para o carregamento de navegação suave para LCP, e não aquelas para interações subsequentes.

Portanto, o interactionId, e não o navigationId, deve ser usado para mapear entradas interaction-contentful-paint para soft-navigation-entries e obter o URL correto. Isso vai processar todas as entradas com navigationIds antigos e filtrar as entradas interaction-contentful-paint que não devem ser consideradas para o LCP.

Além disso, processe primeiro a função getLargestInteractionContentfulPaint() das entradas soft-navigation para lidar com as entradas interaction-contentful-paint que ocorreram antes da emissão do soft-navigation entries.

Como receber o startTime de navegações suaves

Todos os tempos de performance, incluindo os de navegações suaves, e as entradas usadas para calcular as métricas das Core Web Vitals são informados como um tempo desde a navegação inicial "completa" da página. Portanto, o tempo de início da navegação suave precisa ser subtraído dos tempos de métricas de carregamento de navegação suave (por exemplo, LCP) para que sejam informados em relação a esse tempo de navegação suave.

O horário de início da navegação pode ser obtido de maneira semelhante, mapeando para a entrada soft-navigation apropriada e usando o startTime dela.

O startTime é o horário da interação inicial (por exemplo, um clique em um botão) que iniciou a navegação suave. Isso é um pouco diferente das "navegações completas", em que o "horário de início" é quando a nova página é "confirmada" para o navegador e depois que parte do código do manipulador de eventos é executada. Os tempos de início da navegação suave também incluem esse código do manipulador de eventos, já que medimos a partir do tempo de início da interação.

Medir as Core Web Vitals por navegação suave

Para medir as Core Web Vitals, ouça as entradas soft-navigation e redefina as métricas ao recebê-las. A FCP pode ser emitida com base no presentationTime, e a LCP pode ser inicializada na entrada getLargestInteractionContentfulPaint(). A INP e a CLS precisam ser inicializadas como 0, assim como em um carregamento de página.

O LCP, o INP e o CLS podem ser medidos e monitorados como de costume, exceto quando interaction-contentful-paint é usado para o LCP, desde que o interactionId corresponda. O interactionId pode ser usado para nomear as entradas de um URL, conforme discutido anteriormente.

Os tempos ainda serão retornados em relação ao horário de início da navegação "forçada" original. Portanto, para calcular o LCP de uma navegação suave, por exemplo, você precisa usar a marcação de tempo interaction-contentful-paint e subtrair o horário de início da navegação suave adequado, conforme detalhado anteriormente, para ter um tempo relativo à navegação suave.

Algumas métricas são medidas ao longo da vida útil da página: o LCP, por exemplo, pode mudar até que uma interação ocorra. O CLS e o INP podem ser atualizados até que a página seja deixada, independentemente das interações. Portanto, as métricas da navegação anterior precisam ser finalizadas à medida que cada nova navegação suave ocorre. Isso significa que as métricas iniciais de navegação "difícil" podem ser finalizadas antes do normal ao medir as Core Web Vitals com navegações suaves.

Da mesma forma, ao começar a medir as métricas para a nova navegação suave dessas métricas de longa duração, elas precisarão ser "redefinidas" ou "reinicializadas" e tratadas como novas métricas, sem memória dos valores definidos para "páginas" anteriores. Ou seja, o entendimento do que é a "maior" exibição, interação até a próxima exibição ou mudança de layout é redefinido para permitir a medição novamente do zero.

Como o conteúdo que permanece o mesmo entre as navegações deve ser tratado?

O LCP para navegações suaves (calculado em interaction-contentful-paint) mede apenas novas renderizações e aquelas associadas à interação que causou a navegação. Isso pode resultar em um LCP diferente de um carregamento a frio da navegação flexível para um carregamento flexível.

Por exemplo, uma página que inclui uma imagem do banner grande, que é o elemento LCP, mas o texto abaixo dela muda a cada navegação suave. O carregamento de página inicial vai sinalizar a imagem do banner como o elemento LCP e basear o tempo da LCP nela. Para as navegações suaves subsequentes, o texto abaixo será o maior elemento renderizado após a navegação suave e será o novo elemento LCP. No entanto, se a página for carregada com um link direto no URL de navegação suave, a imagem do banner será uma nova renderização e, portanto, poderá ser considerada o elemento LCP.

Da mesma forma, uma animação pode atualizar parte da página continuamente, sem relação com qualquer navegação suave que aconteça. Novas renderizações devido a essa animação de plano de fundo não seriam consideradas para o LCP da nova navegação suave. No entanto, eles podem ser considerados para LCP se a página for recarregada desse URL.

Como mostram esses exemplos, o elemento LCP para a navegação suave pode ser informado de maneira diferente, dependendo de como a página é carregada. Da mesma forma, carregar uma página com um link fixo mais abaixo pode resultar em um elemento LCP diferente para navegações completas.

Como medir o TTFB?

O Time to First Byte (TTFB) para um carregamento de página convencional representa o tempo em que os primeiros bytes da solicitação original são retornados.

Para uma navegação suave, essa é uma questão mais complicada. Devemos medir a primeira solicitação feita para a nova página? E se todo o conteúdo já existir no app e não houver outras solicitações? E se essa solicitação for feita com antecedência usando um pré-busca? E se uma solicitação não estiver relacionada à navegação suave do ponto de vista do usuário (por exemplo, uma solicitação de análise)?

Um método mais simples é informar um TTFB de 0 para navegações suaves, de maneira semelhante ao que recomendamos para restaurações do cache de avanço e retorno. Esse é o método que a biblioteca web-vitals usa para navegações suaves e o que recomendamos para essa métrica no momento.

Você deve medir as Core Web Vitals com as duas metodologias?

Embora essas novas APIs sejam limitadas apenas a navegadores baseados no Chromium, os sites podem querer medir ambos os tipos de navegação dividindo por navegações suaves e continuando a dividir por navegações completas. Isso permitiria a comparação entre navegadores e tendências históricas.

Para o LCP, isso significa considerar apenas entradas largest-contentful-paint para a maneira atual e entradas largest-contentful-paint e interaction-contentful-paint para a nova maneira.

Para CLS e INP, isso significa medir essas métricas em todo o ciclo de vida da página, no estado em que se encontra, e dividir separadamente a linha do tempo por navegações suaves para medir valores separados de CLS e INP para o novo.

As métricas precisariam ser sinalizadas e armazenadas duas vezes para análise.

Use a biblioteca web-vitals para medir as Core Web Vitals em navegações suaves

A maneira mais fácil de considerar todas as nuances é usar a biblioteca JavaScript web-vitals, que tem suporte para navegações leves a partir da v6.0.0. Isso pode ser medido da seguinte maneira (substituindo doTraditionalProcessing e doSoftNavProcessing conforme necessário):

import {
  onTTFB,
  onFCP,
  onLCP,
  onCLS,
  onINP,
} from 'https://unpkg.com/web-vitals@soft-navs/dist/web-vitals.js?module';

function doTraditionalProcessing(callback) {
  ...
}

function doSoftNavProcessing(callback) {
  ...
}

onTTFB(doTraditionalProcessing);
onFCP(doTraditionalProcessing);
onLCP(doTraditionalProcessing);
onCLS(doTraditionalProcessing);
onINP(doTraditionalProcessing);

onTTFB(doSoftNavProcessing, {reportSoftNavs: true});
onFCP(doSoftNavProcessing, {reportSoftNavs: true});
onLCP(doSoftNavProcessing, {reportSoftNavs: true});
onCLS(doSoftNavProcessing, {reportSoftNavs: true});
onINP(doSoftNavProcessing, {reportSoftNavs: true});

A biblioteca web-vitals também garante que as métricas sejam informadas no URL correto conforme observado anteriormente, já que incluem o navigationId e um navigationURL nas entradas fornecidas ao callback.

A biblioteca web-vitals informa as seguintes métricas para navegações suaves:

Métrica Detalhes
TTFB Informado como 0.
First Contentful Paint (FCP) O tempo da primeira exibição de conteúdo, em relação ao horário de início da navegação suave, da interação que a acionou. As renderizações existentes da navegação anterior ou não associadas à interação não são consideradas.
LCP O tempo da maior exibição de conteúdo, em relação ao horário de início da navegação suave, da interação que acionou a navegação suave. As renderizações existentes da navegação anterior, que não estão associadas à interação, não são consideradas. Como de costume, isso pode continuar sendo atualizado até que a página (ou a navegação suave) seja deixada, já que só então o LCP pode ser finalizado.
INP O INP entre os tempos de navegação. Como de costume, isso pode continuar sendo atualizado até que a página (ou a navegação suave) seja deixada, pois só então a INP poderá ser finalizada. Um valor 0 não será informado se não houver interações. A interação que causa uma navegação suave geralmente está associada à navegação anterior (de onde se está navegando), em vez da nova navegação (para onde se está navegando), já que a primeira renderização é necessária para causar a navegação suave. Isso é semelhante às navegações completas, em que um clique em um link pode ter um INP, mas que seria associado à página em que o clique ocorreu.
CLS A maior janela de turnos entre os horários de navegação. Como de costume, isso pode continuar sendo atualizado até que a página (ou a navegação suave) seja deixada, já que só então o CLS pode ser finalizado. A observação do CLS associado ao evento de navegação pode ser excluída (se ocorrer em até 500 ms da interação), associada à navegação anterior (se a mudança ocorrer antes da atualização do URL) ou associada à nova navegação (se a mudança ocorrer após a conclusão da navegação suave).

Essas mudanças vão fazer parte das medições das Core Web Vitals?

O objetivo final é fornecer um meio de medir melhor a performance como experiências de usuários reais. Sim, o objetivo é incluir essas métricas nas medições das Core Web Vitals, conforme exposto por todas as ferramentas após o lançamento da API.

Como as navegações suaves serão informadas no CrUX?

Ainda não sabemos exatamente como as navegações suaves serão informadas no CrUX quando o recurso for lançado. Vamos anunciar como a CrUX vai mudar quando tivermos mais informações para compartilhar aqui.

Como lidar com navegações suaves em outros navegadores?

É difícil detectar navegações suaves de forma programática em navegadores que não oferecem suporte à API, que é o motivo pelo qual trabalhamos nela.

É possível usar a API Navigation para monitorar mudanças de URL que podem permitir o corte do INP por URL (e da mesma forma o CLS, embora ele seja exclusivo do Chromium no momento, então não seria medido de qualquer maneira). No entanto, isso não aborda as métricas de renderização (FCP e LCP), que só podem ser aproximadas.

Ao mesmo tempo, acreditamos que os insights oferecidos por essa API são valiosos demais para serem ignorados, tanto na medição do tempo de navegações suaves quanto na atribuição das métricas à navegação correta. Recomendamos usar essa nova API, apesar da falta de suporte entre navegadores no momento. Assim como quando as Core Web Vitals foram lançadas, os problemas identificados e as soluções de desempenho provavelmente vão afetar todos os navegadores, mesmo que a visibilidade esteja limitada apenas aos navegadores baseados no Chromium por enquanto.

Vamos continuar trabalhando no processo de padronização e interagindo com os outros fornecedores de navegadores para mostrar a importância dessa API.

Feedback

Estamos buscando feedback sobre essa API nos seguintes lugares:

Se você estiver em dúvida, não se preocupe muito. Preferimos receber o feedback em qualquer um dos lugares e vamos analisar os problemas nos dois locais e redirecioná-los para o local correto.

Registro de alterações

Como essa API foi desenvolvida, ela passou por várias mudanças, mais do que as APIs estáveis. Consulte o registro de mudanças das navegações suaves para mais detalhes.

Conclusão

O recurso de navegações suaves é uma abordagem interessante de como a iniciativa Core Web Vitals pode evoluir para medir um padrão comum na Web moderna que está ausente das nossas métricas. Reunimos um feedback considerável da comunidade da Web em geral e estamos animados com o potencial dessa API.

Agradecimentos

Imagem em miniatura de Jordan Madrid no Unsplash

Este trabalho é uma continuação de um projeto iniciado por Yoav Weiss quando ele trabalhava no Google. Agradecemos a Yoav pelos esforços nessa API.