Volver al blog

Soft Navigations: Medir el Rendimiento de las SPA como lo Hace el Navegador

Las heurísticas de soft navigation de Chrome por fin permiten que los Core Web Vitals se asocien a los cambios de ruta en el cliente. Así funciona la API y así se mide sin vigilancia.

Durante una década, los Core Web Vitals solo describían la primera página que cargaba un visitante. Cada cambio de ruta posterior en una single-page application era invisible para las métricas. El experimento de soft navigations de Chrome cierra esa brecha, y cambia cómo una analítica centrada en la privacidad debería medir el rendimiento real del usuario.

El punto ciego que resuelven las soft navigations

Una hard navigation tradicional descarga el documento y carga otro. El navegador reinicia su línea de tiempo de rendimiento, dispara un nuevo LCP y empieza a contar CLS e INP desde cero. Las herramientas de campo como CrUX atribuyen todo a esa única URL.

Las SPA no funcionan así. Tras la carga inicial, React Router, el App Router de Next.js o SvelteKit intercambian el contenido en su sitio usando la History API. Ningún documento se descarga, así que no comienza ninguna nueva línea de tiempo de rendimiento. Un usuario puede recorrer diez "páginas" mientras cada Core Web Vital sigue anclado a la URL de entrada.

El resultado lo conoce cualquiera que haya auditado una SPA: la ruta de aterrizaje parece rápida, y las interacciones lentas más adentro de la aplicación nunca aparecen en los datos.

Cómo detecta Chrome una soft navigation

La heurística de Chrome exige que tres cosas ocurran en orden antes de registrar una soft navigation:

  1. La navegación se inicia por una interacción del usuario: un clic o una pulsación de tecla.
  2. La URL se modifica mediante la History API o la Navigation API.
  3. Una modificación del DOM sigue a la interacción, cambiando un elemento del DOM que ya existía.

Esta secuencia es deliberadamente estricta. Un pushState en segundo plano para analítica, un carrusel que avanza solo o un cambio de URL sin interacción no califican. Esa precisión importa: significa que una soft navigation se corresponde con algo que un humano hizo de verdad, no con actividad incidental de scripts.

La superficie de la API

Las soft navigations se exponen a través del PerformanceObserver estándar usando un tipo de entrada dedicado. Te suscribes por cada observer:

new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log(entry.name, entry.startTime);
  }
}).observe({ type: "soft-navigation", buffered: true });

Más importante aún: otras entradas de rendimiento ganan un navigationId. Las entradas de LCP, layout-shift y event-timing emitidas tras una soft navigation llevan el nuevo ID, así que puedes reatribuir cada Core Web Vital a la ruta en la que el usuario estaba realmente:

new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // entry.navigationId vincula este LCP con una soft navigation concreta
    send({ metric: "LCP", value: entry.startTime, navId: entry.navigationId });
  }
}).observe({ type: "largest-contentful-paint", buffered: true });

Hoy esto vive tras chrome://flags/#soft-navigation-heuristics y un origin trial, con exposición limitada en CrUX. Todavía no es el comportamiento por defecto en Chrome estable, así que trata las cifras de campo como orientativas, no como definitivas. La biblioteca web-vitals expone los mismos datos mediante su opción reportSoftNavs, que es la forma práctica de conectarlo sin escribir observers a mano.

Por qué esto pertenece a una analítica centrada en la privacidad

Los datos de soft navigation son puro timing. No contienen identificador, ni cookie, ni nada que sobreviva a la sesión de la página: una duración, un tipo de elemento aproximado, una ruta. Es justo el tipo de señal que una herramienta sin cookies puede recopilar sin tocar la maquinaria del consentimiento.

El tracker ya engancha history.pushState para contar cambios de ruta en SPA. Las soft navigations refinan ese mismo gancho: en lugar de preguntar solo ¿cambió la ruta?, puedes preguntar ¿fue esta una navegación impulsada por interacción y cómo rindió?. Las entradas de rendimiento viajan junto al beacon de pageview existente hacia /collect, añadiendo medición de campo sin añadir peso al script de menos de 2 KB ni romper el modelo de identidad por hash diario.

La trampa a evitar es tratar las soft navigations como una razón para recopilar más. Algunos proveedores de RUM usarán la nueva atribución para coser recorridos de navegación por usuario a lo largo de una sesión: justo el patrón de vigilancia que la analítica sin cookies existe para rechazar. La métrica es valiosa precisamente porque puede mantenerse agregada: INP mediano por ruta, distribución de LCP por ruta, sin camino de vuelta a una persona.

Las soft navigations hacen medibles por primera vez las partes más profundas y lentas de tu aplicación. Recopila el timing, descarta todo lo demás, y obtienes la imagen de rendimiento sin el perfil.