Experimentar con la medición de navegaciones suaves

Fecha de publicación: 1 de febrero de 2023; última actualización: 31 de julio de 2025

Desde su lanzamiento, la iniciativa de Métricas web esenciales ha buscado medir la experiencia real del usuario de un sitio web, en lugar de los detalles técnicos detrás de cómo se crea o carga un sitio web. Las tres métricas de Core Web Vitals se crearon como métricas centradas en el usuario, una evolución de las métricas técnicas existentes, comoDOMContentLoaded o load, que medían los tiempos que a menudo no estaban relacionados con la forma en que los usuarios percibían el rendimiento de la página. Por este motivo, la tecnología utilizada para crear el sitio no debería afectar la puntuación, siempre y cuando el sitio tenga un buen rendimiento.

La realidad siempre es un poco más compleja que el ideal, y las métricas de Métricas web esenciales nunca admitieron por completo la popular arquitectura de aplicación de una sola página. En lugar de cargar páginas web individuales y distintas a medida que el usuario navega por el sitio, estas aplicaciones web usan las llamadas "navegaciones suaves", en las que el contenido de la página se cambia con JavaScript. En estas aplicaciones, la ilusión de una arquitectura de página web convencional se mantiene alterando la URL y enviando las URLs anteriores al historial del navegador para permitir que los botones de atrás y adelante funcionen como el usuario esperaría.

Muchos frameworks de JavaScript usan este modelo, pero cada uno de una manera diferente. Dado que esto está fuera de lo que el navegador tradicionalmente entiende como una "página", medirlo siempre ha sido difícil: ¿dónde se debe trazar la línea entre una interacción en la página actual y considerarla como una página nueva?

El equipo de Chrome ha estado considerando este desafío durante algún tiempo y busca estandarizar una definición de qué es una "navegación suave" y cómo se pueden medir las Métricas web esenciales para este tipo de navegación, de manera similar a como se miden los sitios web implementados en la arquitectura convencional de varias páginas (MPA).

Hemos trabajado arduamente para mejorar la API desde la última prueba de origen y ahora les pedimos a los desarrolladores que prueben la iteración más reciente y proporcionen comentarios sobre el enfoque antes de que se lance.

¿Qué es la navegación suave?

Creamos la siguiente definición de navegación suave:

  • La navegación se inicia con una acción del usuario.
  • La navegación genera un cambio visible en la URL para el usuario y un cambio en el historial.
  • La navegación genera un cambio en el DOM.

En algunos sitios, estas heurísticas pueden generar falsos positivos (que los usuarios no considerarían realmente como una "navegación") o falsos negativos (en los que el usuario sí considera que hubo una "navegación" a pesar de no cumplir con estos criterios). Agradecemos tus comentarios sobre las heurísticas en el repositorio de especificaciones de navegación suave.

¿Cómo implementa Chrome las navegaciones suaves?

Una vez que se habiliten las heurísticas de navegación suave (más información en la siguiente sección), Chrome cambiará la forma en que informa algunas métricas de rendimiento:

  • Se emitirá un evento soft-navigation PerformanceTiming después de que se detecte cada navegación no definitiva.
  • Se emitirá un nuevo interaction-contentful-paint después de las interacciones que provoquen una pintura significativa. Se puede usar para medir el Largest Contentful Paint (LCP) en las navegaciones suaves cuando dicho procesamiento abarca una navegación suave. Ten en cuenta que la implementación original de este restablecimiento restableció la métrica largest-contentful-paint, lo que permitió que se volviera a emitir, pero nos decidimos por este enfoque alternativo por su simplicidad y mayor alcance futuro.
  • Se agregará un atributo navigationId a cada uno de los tiempos de rendimiento (first-paint, first-contentful-paint, largest-contentful-paint, interaction-contentful-paint, first-input-delay, event y layout-shift) correspondientes a la entrada de navegación con la que se relacionó el evento, lo que permitirá calcular el Procesamiento de imagen con contenido más grande (LCP), el Cambio de diseño acumulado (CLS) y la Interacción con la siguiente pintura (INP), y atribuirlos a la URL correcta.

Estos cambios permitirán que las métricas web esenciales y algunas de las métricas de diagnóstico asociadas se midan por navegación de página, aunque hay algunos matices que se deben tener en cuenta.

¿Cuáles son las implicaciones de habilitar las navegaciones suaves en Chrome?

Estos son algunos de los cambios que los propietarios de sitios deben tener en cuenta después de habilitar esta función:

  • Las métricas de CLS y INP se pueden segmentar por URL de navegación suave, en lugar de medirse durante la duración de todo el ciclo de vida de la página.
  • La entrada largest-contentul-paint ya está finalizada en una interacción, por lo que solo se usa para medir el LCP de navegación "difícil" inicial, por lo que no se necesita lógica adicional para cambiar la forma en que se mide.
  • La nueva métrica interaction-contentful-paint se emitirá a partir de las interacciones, que se pueden usar para medir el LCP en las navegaciones suaves.
  • Para atribuir las navegaciones suaves a la URL correcta, es posible que debas tener en cuenta el nuevo atributo navigationID en tus entradas de rendimiento en el código de tu aplicación.
  • No todos los usuarios admitirán esta API de navegación suave, en especial en versiones anteriores de Chrome y en quienes usen otros navegadores. Ten en cuenta que es posible que algunos usuarios no registren las métricas de navegación suave, incluso si registran las métricas de Métricas web esenciales.
  • Como se trata de una nueva función experimental que no está habilitada de forma predeterminada, los sitios deben probarla para detectar efectos secundarios no deseados.

Consulta con tu proveedor de RUM si admite la medición de las Métricas web esenciales por navegación suave. Muchos planean probar este nuevo estándar y tendrán en cuenta las consideraciones anteriores. Mientras tanto, algunos proveedores también permiten mediciones limitadas de las métricas de rendimiento basadas en sus propias heurísticas.

Para obtener más información sobre cómo medir las métricas de las navegaciones suaves, consulta la sección sobre cómo medir las métricas web esenciales por navegación suave.

¿Cómo habilito las navegaciones suaves en Chrome?

Las navegaciones suaves no están habilitadas de forma predeterminada en Chrome, pero están disponibles para la experimentación si se habilita explícitamente esta función.

Los desarrolladores pueden habilitar esta opción activando la marca en chrome://flags/#soft-navigation-heuristics. La opción "Enabled Advanced Paint Attribution (Eager Cached Pre-Paint Walk)" es la recomendada y pronto será la predeterminada. También se puede habilitar con los argumentos de la línea de comandos de --enable-features=SoftNavigationHeuristics:mode/advanced_paint_attribution cuando se inicia Chrome.

En el caso de los sitios web que deseen habilitar esta función para que todos sus visitantes vean el impacto, se ejecutará una prueba de origen a partir de Chrome 139 que se podrá habilitar registrándose en la prueba y agregando un elemento meta con el token de la prueba de origen en el encabezado HTML o HTTP. Consulta la publicación Comienza a usar las pruebas de origen para obtener más información.

Los propietarios de sitios pueden optar por incluir la prueba de origen en sus páginas para todos los usuarios o solo para un subconjunto de ellos. Ten en cuenta la sección de implicaciones anterior sobre cómo esto cambia la forma en que se pueden informar tus métricas, especialmente si habilitas esta prueba de origen para una gran proporción de tus usuarios. Ten en cuenta que CrUX seguirá registrando las métricas de la misma manera, independientemente de este parámetro de configuración de navegación suave, por lo que no se verá afectado por esas implicaciones. También se debe tener en cuenta que las pruebas de origen también se limitan a habilitar funciones experimentales en un máximo del 0.5% de todas las cargas de páginas de Chrome como mediana durante 14 días, pero esto solo debería ser un problema para los sitios muy grandes.

¿Cómo puedo medir las navegaciones suaves?

Una vez que se habilite el experimento de navegación suave, las métricas se registrarán con la API de PerformanceObserver, como sucede con otras métricas. Sin embargo, hay algunas consideraciones adicionales que se deben tener en cuenta para estas métricas.

Cómo informar navegaciones suaves

Puedes usar un PerformanceObserver para observar las navegaciones suaves. A continuación, se muestra un ejemplo de fragmento de código que registra entradas de navegación suave en la consola, incluidas las navegaciones suaves anteriores en esta página con la opción buffered:

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

Se puede usar para finalizar las métricas de página de ciclo de vida completo de la navegación anterior.

Informa las métricas en la URL correspondiente

Como las navegaciones suaves solo se pueden ver después de que ocurren, algunas métricas deberán finalizarse en este evento y, luego, se generarán informes para la URL anterior, ya que la URL actual reflejará la URL actualizada de la página nueva.

El atributo navigationId del PerformanceEntry adecuado se puede usar para vincular el evento a la URL correcta. Esto se puede consultar con la API de 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;

Este pageUrl se debe usar para informar las métricas en la URL correcta, en lugar de la URL actual que se haya usado en el pasado.

Cómo obtener el startTime de las navegaciones suaves

La hora de inicio de la navegación se puede obtener de manera similar:

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;

El objeto startTime es la hora de la interacción inicial (por ejemplo, un clic en un botón) que inició la navegación suave.

Todos los tiempos de rendimiento, incluidos los de las navegaciones suaves, se registran como un tiempo desde el tiempo de navegación de página "dura" inicial. Por lo tanto, se necesita la hora de inicio de la navegación suave para establecer como referencia los tiempos de las métricas de carga de la navegación suave (por ejemplo, LCP) en relación con este tiempo de navegación suave.

Mide las Métricas web esenciales por navegación suave

Para incluir entradas de métricas de navegación suave, debes incluir includeSoftNavigationObservations: true en la llamada a observe de tu observador de rendimiento.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('Layout Shift time:', entry);
  }
}).observe({type: 'layout-shift', buffered: true, includeSoftNavigationObservations: true});

Con los cambios más recientes en la API, la marca includeSoftNavigationObservations ya no es necesaria y es probable que se quite en el futuro, pero, por ahora, se necesita esta habilitación explícita a nivel del observador de rendimiento, además de habilitar la función de navegación suave en Chrome.

Los tiempos seguirán devolviéndose en relación con la hora de inicio de navegación "fija" original. Por ejemplo, para calcular el LCP de una navegación suave, deberás tomar el tiempo de interaction-contentful-paint y restarle el tiempo de inicio de navegación suave adecuado, como se detalló anteriormente, para obtener un tiempo relativo a la navegación suave. Por ejemplo, para el 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});

Algunas métricas se miden tradicionalmente a lo largo de la vida útil de la página: el LCP, por ejemplo, puede cambiar hasta que se produce una interacción. El CLS y el INP se pueden actualizar hasta que se abandone la página. Por lo tanto, es posible que cada "navegación" (incluida la navegación original) deba finalizar las métricas de la página anterior a medida que se produce cada nueva navegación suave. Esto significa que las métricas de navegación "duras" iniciales pueden finalizarse antes de lo habitual.

Del mismo modo, cuando se comience a medir las métricas de la nueva navegación suave de estas métricas de larga duración, las métricas deberán "restablecerse" o "reinicializarse" y tratarse como métricas nuevas, sin memoria de los valores que se establecieron para las "páginas" anteriores.

¿Cómo se debe tratar el contenido que permanece igual entre las navegaciones?

El LCP para las navegaciones suaves (calculado a partir de interaction-contentful-paint) solo medirá las nuevas renderizaciones. Esto puede generar un LCP diferente, por ejemplo, desde una carga en frío de esa navegación suave a una carga suave.

Por ejemplo, considera una página que incluye una imagen de banner grande que es el elemento LCP, pero el texto que se encuentra debajo cambia con cada navegación suave. La carga inicial de la página marcará la imagen del banner como el elemento LCP y basará la sincronización del LCP en ella. En las navegaciones suaves posteriores, el texto que aparece debajo será el elemento más grande que se renderice después de la navegación suave y será el nuevo elemento LCP. Sin embargo, si se carga una página nueva con un vínculo directo a la URL de navegación suave, la imagen del banner será una nueva pintura y, por lo tanto, será apta para considerarse como el elemento LCP.

Como se muestra en este ejemplo, el elemento LCP para la navegación suave se puede registrar de manera diferente según cómo se cargue la página, de la misma manera que cargar una página con un vínculo de anclaje más abajo en la página puede generar un elemento LCP diferente.

¿Cómo se mide el TTFB?

El tiempo hasta el primer byte (TTFB) para la carga de una página convencional representa el tiempo que tardan en devolverse los primeros bytes de la solicitud original.

En el caso de una navegación suave, esta es una pregunta más difícil. ¿Deberíamos medir la primera solicitud realizada para la página nueva? ¿Qué sucede si todo el contenido ya existe en la app y no hay solicitudes adicionales? ¿Qué sucede si esa solicitud se realiza con anticipación con una recuperación previa? ¿Qué sucede si una solicitud no está relacionada con la navegación suave desde la perspectiva del usuario (por ejemplo, es una solicitud de Analytics)?

Un método más simple es registrar un TTFB de 0 para las navegaciones suaves, de manera similar a lo que recomendamos para las restauraciones de la memoria caché atrás/adelante. Este es el método que usa la biblioteca web-vitals para las navegaciones suaves.

En el futuro, es posible que admitamos formas más precisas de saber qué solicitud es la "solicitud de navegación" de la navegación suave y podremos tener mediciones del TTFB más precisas. Pero eso no forma parte de la implementación actual.

¿Cómo medir tanto lo antiguo como lo nuevo?

Durante este experimento, se recomienda que sigas midiendo tus Métricas web esenciales de la manera actual, en función de las navegaciones de página "duras", para que coincidan con lo que CrUX medirá y registrará como el conjunto de datos oficial de la iniciativa de Métricas web esenciales.

Las navegaciones suaves se deben medir además de estas para que puedas ver cómo se podrían medir en el futuro y para que tengas la oportunidad de proporcionar comentarios al equipo de Chrome sobre cómo funciona esta implementación en la práctica. Esto te ayudará a ti y al equipo de Chrome a darle forma a la API en el futuro.

En el caso del LCP, esto significa considerar solo las entradas de largest-contentful-paint para la forma anterior y las entradas de largest-contentful-paint y interaction-contentful-paint para la forma nueva.

En el caso del CLS y el INP, esto significa medirlos en todo el ciclo de vida de la página, como se hacía antes, y segmentar por separado la línea de tiempo por navegaciones suaves para medir valores de CLS y de INP separados para la nueva forma.

Usa la biblioteca web-vitals para medir las Métricas web esenciales en las navegaciones suaves

La forma más sencilla de tener en cuenta todos los matices es usar la biblioteca de JavaScript web-vitals, que tiene compatibilidad experimental con las navegaciones suaves en un soft-navs branch independiente (que también está disponible en npm y unpkg). Esto se puede medir de la siguiente manera (reemplaza doTraditionalProcessing y doSoftNavProcessing según corresponda):

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});

Asegúrate de que las métricas se registren en la URL correcta como se indicó anteriormente.

La biblioteca de web-vitals informa las siguientes métricas para las navegaciones suaves:

Métrica Detalles
TTFB Se informa como 0.
FCP Solo se informa el primer FCP de la página.
LCP Es el tiempo del siguiente procesamiento de imagen con contenido más grande, en relación con la hora de inicio de la navegación suave. No se tienen en cuenta las pinturas existentes de la navegación anterior. Por lo tanto, el LCP será >= 0. Como de costumbre, se informará sobre esto cuando haya una interacción o cuando la página pase a segundo plano, ya que solo entonces se puede finalizar el LCP.
CLS Es el intervalo más grande de turnos entre los tiempos de navegación. Como de costumbre, esto sucede cuando la página pasa a segundo plano, ya que solo entonces se puede finalizar el CLS. Se informa un valor de 0 si no hay cambios.
INP El INP entre los tiempos de navegación. Como de costumbre, se registrará cuando haya una interacción o cuando la página pase a segundo plano, ya que solo entonces se puede finalizar el INP. No se informa un valor de 0 si no hay interacciones.

¿Estos cambios formarán parte de las mediciones de las Métricas web esenciales?

Este experimento de navegación suave es exactamente eso: un experimento. Queremos evaluar la heurística y ver si refleja con mayor precisión la experiencia del usuario antes de tomar una decisión sobre si se integrará en la iniciativa de las métricas web esenciales. Nos entusiasma la posibilidad de este experimento, pero no podemos garantizar si reemplazará las mediciones actuales ni cuándo lo hará.

Valoramos los comentarios de los desarrolladores web sobre el experimento, la heurística utilizada y si creen que refleja con mayor precisión la experiencia. El repositorio de GitHub de navegación suave es el mejor lugar para proporcionar esos comentarios, aunque los errores individuales relacionados con la implementación de Chrome deben plantearse en el seguimiento de problemas de Chrome.

¿Cómo se informarán las navegaciones suaves en CrUX?

Aún no se determinó cómo se registrarán exactamente las navegaciones suaves en CrUX si este experimento tiene éxito. No necesariamente se tratarán de la misma manera que las navegaciones "duras" actuales.

En algunas páginas web, las navegaciones suaves son casi idénticas a las cargas de página completas en lo que respecta al usuario, y el uso de la tecnología de aplicación de una sola página es solo un detalle de implementación. En otros, pueden ser más similares a una carga parcial de contenido adicional.

Por lo tanto, es posible que decidamos registrar estas navegaciones suaves por separado en CrUX o, tal vez, ponderarlas cuando calculemos las Métricas web esenciales para una página o un grupo de páginas determinados. También es posible que podamos excluir por completo la navegación suave de carga parcial a medida que evolucione la heurística.

El equipo se concentra en la implementación heurística y técnica, lo que nos permitirá juzgar el éxito de este experimento, por lo que no se tomó ninguna decisión en estos frentes.

Comentarios

Estamos buscando activamente comentarios sobre este experimento en los siguientes lugares:

Registro de cambios

Como esta API se encuentra en fase experimental, se le realizan varios cambios, más que a las APIs estables. Puedes consultar el registro de cambios de las heurísticas de navegación suave para obtener más detalles.

Conclusión

El experimento de navegación suave es un enfoque interesante sobre cómo podría evolucionar la iniciativa de Métricas web esenciales para medir un patrón común en la Web moderna que falta en nuestras métricas. Si bien este experimento aún está en sus primeras etapas y queda mucho por hacer, poner a disposición de la comunidad web en general los avances logrados hasta el momento para que experimente con ellos es un paso importante. Recopilar los comentarios de este experimento es otra parte fundamental del proceso, por lo que recomendamos a quienes estén interesados en este desarrollo que aprovechen esta oportunidad para ayudar a definir la API y garantizar que represente lo que esperamos poder medir con ella.

Agradecimientos

Imagen en miniatura de Jordan Madrid en Unsplash

Este trabajo es una continuación del trabajo que comenzó Yoav Weiss cuando estaba en Google. Agradecemos a Yoav por su trabajo en esta API.