Publicação: 1º de fevereiro de 2023, Última atualização: 31 de julho de 2025
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 aplicativos 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 está considerando esse desafio há algum tempo e quer 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).
Estamos trabalhando para melhorar a API desde o último teste de origem e agora pedimos aos desenvolvedores que testem a iteração mais recente e enviem feedback sobre a abordagem antes do lançamento.
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 e uma mudança no histórico.
- A navegação resulta em uma mudança no DOM.
Para alguns sites, essas heurísticas podem gerar 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). Aceitamos feedback sobre as heurísticas no repositório de especificações de navegação suave.
Como o Chrome implementa navegações suaves?
Depois que as heurísticas de navegação suave forem ativadas (mais detalhes na próxima seção), o Chrome vai mudar a forma como informa algumas métricas de desempenho:
- Um evento
soft-navigation
PerformanceTiming
será emitido após cada navegação suave detectada. - Um novo
interaction-contentful-paint
será emitido após interações que causam uma renderização significativa. Isso pode ser usado para medir a maior exibição de conteúdo (LCP) em navegações suaves quando uma exibição abrange uma navegação suave. A implementação original dessa redefinição permitia que a métricalargest-contentful-paint
fosse reemitida, mas optamos por essa abordagem alternativa por simplicidade e maior escopo futuro. - Um atributo
navigationId
será adicionado a cada um dos tempos de performance (first-paint
,first-contentful-paint
,largest-contentful-paint
,interaction-contentful-paint
,first-input-delay
,event
elayout-shift
) correspondentes à entrada de navegação relacionada ao evento, permitindo que o Largest Contentful Paint (LCP), o Cumulative Layout Shift (CLS) e a Interaction to Next Paint (INP) sejam calculados e atribuídos ao URL correto.
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:
- As métricas CLS e INP podem ser divididas por URL de navegação suave, em vez de serem medidas durante todo o ciclo de vida da página.
- A entrada
largest-contentul-paint
já é finalizada em uma interação. Portanto, ela é usada apenas para medir o LCP inicial de navegação "difícil". Assim, não é necessária nenhuma lógica adicional para mudar a forma como isso é medido. - A nova métrica
interaction-contentful-paint
será emitida das interações, que podem ser usadas para medir o LCP em navegações suaves. - Para atribuir navegações suaves ao URL correto, talvez seja necessário considerar o novo atributo
navigationID
nas entradas de performance no código do aplicativo usando essas entradas. - Nem todos os usuários vão ter suporte para essa API de navegação suave, principalmente em versões mais antigas do Chrome e em outros navegadores. Alguns usuários podem não informar métricas de navegação suave, mesmo que informem métricas de Core Web Vitals.
- Como um novo recurso experimental que não é ativado por padrão, os sites precisam testar essa funcionalidade para detectar efeitos colaterais não intencionais.
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?
As navegações suaves não são ativadas por padrão no Chrome, mas estão disponíveis para testes. Basta ativar o recurso explicitamente.
Para desenvolvedores, isso pode ser ativado ao ativar a flag em chrome://flags/#soft-navigation-heuristics
. A opção "Ativar atribuição de exibição avançada (pré-renderização em cache antecipada)" é a recomendada e será a padrão em breve. Como alternativa, ele pode ser ativado usando os argumentos de linha de comando --enable-features=SoftNavigationHeuristics:mode/advanced_paint_attribution
ao iniciar o Chrome.
Para um site que queira ativar esse recurso para todos os visitantes e ver o impacto, haverá um teste de origem em execução no Chrome 139. Para participar, basta se inscrever e incluir um elemento meta com o token do teste de origem no cabeçalho HTML ou HTTP. Consulte a postagem Começar a usar os testes de origem para mais informações.
Os proprietários de sites podem incluir a avaliação de origem nas páginas para todos ou apenas para um subconjunto de usuários. Consulte a seção de implicações anterior para saber como isso muda a forma como suas métricas podem ser informadas, principalmente se você ativar o teste de origem para uma grande proporção de usuários. A CrUX vai continuar informando as métricas da maneira atual, independente dessa configuração de navegação suave, e não será afetada por essas implicações. Também vale a pena observar que os testes de origem são limitados à ativação de recursos experimentais em um máximo de 0,5% de todos os carregamentos de página do Chrome como uma mediana em 14 dias, mas isso só deve ser um problema para sites muito grandes.
Como posso medir navegações suaves?
Depois que o experimento de navegações suaves for ativado, as métricas serão 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 em relação ao URL adequado
Como as navegações suaves só podem ser vistas depois que ocorrem, algumas métricas precisam ser finalizadas após esse evento e informadas para o URL anterior, já que o URL atual agora vai refletir o URL atualizado da nova página.
O atributo navigationId
do PerformanceEntry
adequado pode ser usado para vincular o evento ao URL correto. Isso pode ser pesquisado com a API PerformanceEntry
:
const softNavEntry =
performance.getEntriesByType('soft-navigation').filter(
(entry) => entry.navigationId === navigationId
)[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const pageUrl = navEntry?.name;
Esse pageUrl
deve ser usado para informar as métricas no URL correto, e não no URL atual que pode ter sido usado no passado.
Como conseguir o startTime
de navegações suaves
O horário de início da navegação pode ser obtido de maneira semelhante:
const softNavEntry =
performance.getEntriesByType('soft-navigation').filter(
(entry) => entry.navigationId === navigationId
)[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const startTime = navEntry?.startTime;
O startTime
é o horário da interação inicial (por exemplo, um clique em um botão) que iniciou a navegação suave.
Todos os tempos de desempenho, incluindo os de navegações leves, são informados como um tempo desde a navegação "completa" inicial da página. Portanto, o horário de início da navegação suave é necessário para definir como base os tempos das métricas de carregamento de navegação suave (por exemplo, LCP) em relação a esse horário de navegação suave.
Medir as Core Web Vitals por navegação suave
Para incluir entradas de métricas de navegação suave, inclua includeSoftNavigationObservations: true
na chamada observe
do observador de performance.
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('Layout Shift time:', entry);
}
}).observe({type: 'layout-shift', buffered: true, includeSoftNavigationObservations: true});
Com as mudanças mais recentes na API, a flag includeSoftNavigationObservations
não é mais necessária e provavelmente será removida no futuro. Por enquanto, essa ativação explícita no nível do observador de performance é necessária, além de ativar o recurso de navegação suave no Chrome.
Os tempos ainda serão retornados em relação ao horário de início da navegação "completa" original. Portanto, para calcular o LCP de uma navegação suave, por exemplo, você precisa usar o 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. Por exemplo, para LCP:
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
const softNavEntry =
performance.getEntriesByType('soft-navigation').filter(
(navEntry) => navEntry.navigationId === entry.navigationId
)[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const startTime = navEntry?.startTime;
console.log('LCP time:', entry.startTime - startTime);
}
}).observe({type: 'interaction-contentful-paint', buffered: true, includeSoftNavigationObservations: true});
Algumas métricas são medidas ao longo da vida útil da página. Por exemplo, o LCP pode mudar até que uma interação ocorra. A CLS e o INP podem ser atualizados até que a página seja deixada. Portanto, cada "navegação" (incluindo a original) pode precisar finalizar as métricas da página anterior à 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.
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 precisam ser "redefinidas" ou "reinicializadas" e tratadas como novas métricas, sem memória dos valores definidos para "páginas" anteriores.
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
) vai medir apenas novas renderizações. Isso pode resultar em um LCP diferente, por exemplo, de um carregamento a frio dessa navegação suave para um carregamento suave.
Por exemplo, uma página que inclui uma imagem de banner grande, que é o elemento LCP, mas o texto abaixo dela muda a cada navegação suave. O carregamento inicial da página vai sinalizar a imagem do banner como o elemento LCP e basear o tempo da LCP nisso. Para as próximas navegações suaves, o texto abaixo será o maior elemento renderizado após a navegação suave e será o novo elemento LCP. No entanto, se uma nova 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.
Como mostra este exemplo, 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 âncora mais abaixo pode resultar em um elemento LCP diferente.
Como medir o TTFB?
O tempo até o primeiro 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 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 leves.
No futuro, talvez ofereçamos suporte a maneiras mais precisas de saber qual solicitação é a "solicitação de navegação" da navegação suave e teremos medições de TTFB mais precisas. Mas isso não faz parte da implementação atual.
Como medir os dois?
Durante esse experimento, recomendamos que você continue medindo as Core Web Vitals da maneira atual, com base em navegações de página "difíceis", para corresponder ao que o CrUX vai medir e informar como o conjunto de dados oficial da iniciativa Core Web Vitals.
As navegações suaves precisam ser medidas além dessas para que você veja como elas podem ser medidas no futuro e para que você possa enviar feedback à equipe do Chrome sobre como essa implementação funciona na prática. Isso vai ajudar você e a equipe do Chrome a moldar a API no futuro.
Para o LCP, isso significa considerar apenas entradas largest-contentful-paint
para a maneira antiga e entradas largest-contentful-paint
e interaction-contentful-paint
para a nova.
Para CLS e INP, isso significa medir essas métricas em todo o ciclo de vida da página, como no método antigo, e dividir separadamente a linha do tempo por navegações suaves para medir valores separados de CLS e INP para o novo método.
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 experimental para navegações leves em um soft-navs branch
separado (também disponível em npm e unpkg). 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';
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});
Verifique se as métricas estão sendo informadas no URL correto, conforme observado anteriormente.
A biblioteca web-vitals
informa as seguintes métricas para navegações suaves:
Métrica | Detalhes |
---|---|
TTFB | Informado como 0. |
First Contentful Paint (FCP) | Apenas o primeiro FCP da página é informado. |
LCP | O tempo da próxima exibição de conteúdo mais relevante, em relação ao tempo de início da navegação suave. As renderizações atuais da navegação anterior não são consideradas. Portanto, o LCP será >= 0. Como de costume, isso será informado em uma interação ou quando a página for colocada em segundo plano, já que só então o LCP poderá ser finalizado. |
CLS | A maior janela de turnos entre os horários de navegação. Como de costume, isso acontece quando a página é colocada em segundo plano, pois só então o CLS pode ser finalizado. Um valor 0 será informado se não houver turnos. |
INP | O INP entre os tempos de navegação. Como de costume, isso será informado em uma interação ou quando a página for colocada em segundo plano, já que só então o INP poderá ser finalizado. Um valor 0 não será informado se não houver interações. |
Essas mudanças vão fazer parte das medições das Core Web Vitals?
Esse experimento de navegação suave é exatamente isso: um experimento. Queremos avaliar as heurísticas e verificar se elas refletem com mais precisão a experiência do usuário antes de decidir se isso será integrado à iniciativa Principais métricas da Web. Estamos muito animados com a possibilidade desse experimento, mas não podemos garantir se ou quando ele vai substituir as medições atuais.
Valorizamos o feedback dos desenvolvedores da Web sobre o experimento, as heurísticas usadas e se você acha que ele reflete melhor a experiência. O repositório do GitHub de navegação suave é o melhor lugar para enviar esse feedback, mas bugs individuais com a implementação do Chrome devem ser informados no rastreador de problemas do Chrome.
Como as navegações suaves serão informadas no CrUX?
Ainda não foi determinado como as navegações suaves serão informadas no CrUX se esse experimento for bem-sucedido. Não é necessariamente uma certeza que eles serão tratados da mesma forma que as navegações "difíceis" atuais.
Em algumas páginas da Web, as navegações leves são quase idênticas aos carregamentos de página completa para o usuário, e o uso da tecnologia de aplicativo de página única é apenas um detalhe de implementação. Em outros, eles podem ser mais parecidos com um carregamento parcial de conteúdo adicional.
Por isso, podemos decidir informar essas navegações suaves separadamente no CrUX ou ponderá-las ao calcular as Core Web Vitals de uma determinada página ou grupo de páginas. Também podemos excluir totalmente a navegação suave de carregamento parcial à medida que a heurística evolui.
A equipe está se concentrando na implementação heurística e técnica, o que nos permitirá julgar o sucesso desse experimento. Portanto, nenhuma decisão foi tomada nessas frentes.
Feedback
Estamos buscando feedback sobre esse experimento nos seguintes lugares:
- O feedback sobre a API deve ser levantado como problemas no GitHub.
- Bugs na implementação do Chromium devem ser informados no rastreador de problemas do Chrome, se ainda não forem um dos problemas conhecidos.
- O feedback geral sobre as métricas vitais da Web pode ser compartilhado em web-vitals-feedback@googlegroups.com.
Se 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 está em fase experimental, ela passa por várias mudanças, mais do que as APIs estáveis. Consulte o registro de mudanças das heurísticas de navegação suave para mais detalhes.
Conclusão
O experimento de navegações suaves é uma abordagem interessante para a evolução da iniciativa Core Web Vitals, que pode medir um padrão comum na Web moderna que não está presente nas nossas métricas. Embora esse experimento ainda esteja em fase inicial e haja muito a ser feito, disponibilizar o progresso até agora para a comunidade da Web experimentar é uma etapa importante. Coletar o feedback desse experimento é outra parte crucial dele. Por isso, incentivamos muito os interessados nesse desenvolvimento a aproveitar essa oportunidade para ajudar a moldar a API e garantir que ela seja representativa do que esperamos medir com ela.
Agradecimentos
Imagem em miniatura de Jordan Madrid no Unsplash
Este trabalho é uma continuação do trabalho iniciado por Yoav Weiss quando ele estava no Google. Agradecemos a Yoav pelos esforços dele nessa API.