Renderiza previamente las páginas en Chrome para navegarlas de forma instantánea

Navegadores compatibles

  • 109
  • 109
  • x
  • x

El equipo de Chrome volvió a renderizar por completo las páginas futuras a las que es probable que navegue un usuario.

Breve historia de la renderización previa

En el pasado, Chrome admitía la sugerencia del recurso <link rel="prerender" href="/next-page">. Sin embargo, no era compatible más allá de Chrome y no era una API muy expresiva.

Este procesamiento previo heredado con la sugerencia de vínculo rel=prerender dejó de estar disponible y se reemplazó por NoState Prefetch, que recuperó los recursos que necesitaba la página futura, pero no realizó una renderización previa completa de la página ni ejecutó JavaScript. NoState Prefetch ayuda a mejorar el rendimiento de la página, ya que mejora la carga de recursos, pero no proporcionará una carga de página instantánea como lo haría una renderización previa completa.

El equipo de Chrome volvió a incorporar la renderización previa completa en Chrome. Para evitar complicaciones con el uso existente y permitir la expansión futura de la renderización previa, este nuevo mecanismo de renderización previa no usará la sintaxis <link rel="prerender"...>, que permanece vigente para NoState Prefetch, y se retirará en algún momento.

¿Cómo se renderiza previamente una página?

Se puede renderizar previamente una página de cuatro maneras, todas con el objetivo de agilizar la navegación:

  1. Cuando escribes una URL en la barra de direcciones de Chrome (también conocida como "cuadro multifunción"), Chrome puede preprocesar la página de forma automática si tienes un alto nivel de certeza de que visitarás esa página en función de tu historial de navegación anterior.
  2. Cuando usas la barra de favoritos, Chrome puede preprocesar automáticamente la página si mantienes el puntero sobre uno de los botones de favoritos.
  3. Cuando escribes un término de búsqueda en la barra de direcciones de Chrome, Chrome puede preprocesar automáticamente la página de resultados de búsqueda cuando el motor de búsqueda lo solicita.
  4. Los sitios pueden usar la API de Speculation Rules para indicarle a Chrome de manera programática qué páginas debe renderizar previamente. Esto reemplaza lo que <link rel="prerender"...> solía hacer y permite que los sitios rendericen previamente una página de forma proactiva según las reglas de especulación en la página. Estos pueden existir de forma estática en las páginas o pueden insertarse dinámicamente por JavaScript según lo considere adecuado el propietario de la página.

En cada uno de estos casos, una renderización previa se comporta como si la página se hubiera abierto en una pestaña invisible en segundo plano y, luego, se “activaba” reemplazando la pestaña en primer plano con esa página renderizada previamente. Si una página se activa antes de que se haya renderizado previamente por completo, su estado actual será "en primer plano" y continuará cargándose, lo que significa que puedes obtener una buena ventaja.

Cuando la página renderizada previamente se abre en un estado oculto, una serie de APIs que causan comportamientos intrusivos (por ejemplo, mensajes) no se activan en este estado, sino que se retrasan hasta que se activa la página. En la pequeña cantidad de casos en los que esto aún no es posible, se cancela la renderización previa. El equipo de Chrome está trabajando para exponer motivos de cancelación de la renderización previa como una API y, además, mejorar las capacidades de Herramientas para desarrolladores para facilitar la identificación de casos extremos.

Impacto de la renderización previa

La renderización previa permite que la página se cargue casi de forma instantánea, como se muestra en el siguiente video:

Ejemplo del impacto de la renderización previa.

El sitio de ejemplo ya es rápido, pero incluso así puedes ver cómo la renderización previa mejora la experiencia del usuario. Por lo tanto, esto también puede tener un impacto directo en las Métricas web esenciales de un sitio, con casi cero LCP, una reducción de CLS (ya que cualquier CLS de carga ocurre antes de la vista inicial) y una INP mejorada (ya que la carga debe completarse antes de que el usuario interactúe).

Incluso cuando una página se activa antes de que se cargue por completo, tener una ventaja inicial en la carga debería mejorar la experiencia de carga. Si se activa un vínculo mientras la renderización previa aún está en curso, la página de renderización previa se moverá al marco principal y continuará cargándose.

Sin embargo, la renderización previa usa memoria y ancho de banda de red adicionales. Ten cuidado de no renderizar en exceso, a costa de los recursos del usuario. Solo realiza una renderización previa cuando haya una alta probabilidad de que se navegue a la página.

Consulta la sección Medición del rendimiento para obtener más información sobre cómo medir el impacto real en el rendimiento en tus estadísticas.

Ver las predicciones de la barra de direcciones de Chrome

En el primer caso de uso, puedes ver las predicciones de Chrome para las URLs en la página chrome://predictors:

La página de Predictors de Chrome se filtró para mostrar predicciones bajas (gris), medias (ámbar) y altas (verde) basadas en el texto ingresado.
Página de Predictors de Chrome.

Las líneas verdes indican un nivel de confianza suficiente para activar la renderización previa. En este ejemplo, escribir "s" genera una confianza razonable (ámbar). Sin embargo, una vez que escribes "sh", Chrome tiene suficiente confianza como para que casi siempre navegues a https://sheets.google.com.

Esta captura de pantalla se tomó en una instalación de Chrome relativamente reciente y se filtraba las predicciones de confianza cero, pero si ves tus propios predictores, es probable que veas muchas más entradas y posiblemente más caracteres necesarios para alcanzar un nivel de confianza lo suficientemente alto.

Estos predictores también impulsan las opciones sugeridas que podrías haber notado en la barra de direcciones:

Función &quot;Typeahead&quot; de la barra de direcciones de Chrome
Función "Escritura anticipada" de la barra de direcciones

Chrome actualizará continuamente sus predictores según lo que escribas y selecciones.

  • Para obtener un nivel de confianza superior al 50% (indicado en ámbar), Chrome se conecta previamente al dominio de forma proactiva, pero no realiza un procesamiento previo de la página.
  • Si el nivel de confianza es superior al 80% (indicado en verde), Chrome renderizará previamente la URL.

La API de Speculation Rules

Para la opción de renderización previa de la API de Speculation Rules, los desarrolladores web pueden insertar instrucciones JSON en sus páginas para informar al navegador qué URLs debe renderizar previamente:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

También puedes usar las reglas del documento (disponibles en Chrome 121), que renderizan previamente los vínculos del documento según los selectores href (según la API de URL Pattern) o los selectores CSS:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "and": [
        { "href_matches": "/*" },
        { "not": {"href_matches": "/wp-admin"}},
        { "not": {"href_matches": "/*\\?*(^|&)add-to-cart=*"}},
        { "not": {"selector_matches": ".do-not-prerender"}},
        { "not": {"selector_matches": "[rel~=nofollow]"}}
      ]
    }
  }]
}
</script>

El equipo de Chrome preparó un Codelab de Speculation Rules que te guiará en el proceso para agregar reglas de especulación a un sitio.

Impulso

Navegadores compatibles

  • 121
  • 121
  • x
  • x

Se usa un parámetro de configuración eagerness para indicar cuándo deben activarse las especulaciones, lo cual es particularmente útil para las reglas de documentos:

  • immediate: Se usa para especular lo antes posible, es decir, en cuanto se observen las reglas de especulación.
  • eager: Este parámetro se comporta de manera idéntica al parámetro de configuración immediate, pero esperamos que, en el futuro, lo ubique entre immediate y moderate.
  • moderate: Realiza especulaciones si mantienes el puntero sobre un vínculo durante 200 milisegundos (o en el evento pointerdown, si es antes, y en dispositivos móviles donde no hay un evento hover).
  • conservative: Especula sobre el puntero o el touchdown.

El eagerness predeterminado para las reglas list es immediate. Las opciones moderate y conservative se pueden usar para limitar las reglas list a las URLs con las que un usuario interactúa con una lista específica. Sin embargo, en muchos casos, las reglas document con una condición where adecuada pueden ser más apropiadas.

El eagerness predeterminado para las reglas document es conservative. Dado que un documento puede constar de varias URLs, se debe usar con precaución el uso de immediate o eager para las reglas document (consulta también la sección Límites de Chrome a continuación).

La configuración de eagerness que se use depende de tu sitio. En el caso de un sitio ligero y estático, especular con más entusiasmo puede tener un costo bajo y ser beneficioso para los usuarios. Es posible que los sitios con arquitecturas más complejas y cargas útiles de páginas más pesadas prefieran reducir el desperdicio mediante especulaciones con menos frecuencia hasta que obtengas una señal más positiva de intención de los usuarios para limitar el desperdicio.

La opción moderate es un punto intermedio, y muchos sitios podrían beneficiarse de la siguiente regla de especulación que renderizaría previamente un vínculo al mantener el puntero sobre el vínculo durante 200 milisegundos o en el evento Pointdown como una implementación básica y, pero poderosa, de reglas de especulación:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "href_matches": "/*"
    },
    "eagerness": "moderate"
  }]
}
</script>

Recuperación previa

Las reglas de especulación también se pueden usar para cargar páginas previamente, sin una renderización previa completa. Este suele ser un buen primer paso para realizar la renderización previa:

<script type="speculationrules">
{
  "prefetch": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

Límites de Chrome

Chrome tiene límites para evitar el uso excesivo de la API de Speculation Rules:

afán Recuperación previa Renderización previa
immediate/eager 50 10
moderate/conservative 2 (FIFO) 2 (FIFO)
Límites de especulación en Chrome.

Los parámetros de configuración de moderate y conservative, que dependen de la interacción del usuario, funcionan de manera primera en entrar, primero en salir (FIFO): después de alcanzar el límite, una nueva especulación hará que se cancele la especulación más antigua y se reemplace por la más nueva para conservar memoria. Una especulación cancelada se puede activar de nuevo (por ejemplo, si se coloca el cursor sobre ese vínculo nuevamente), lo que provocará que se vuelva a especular esa URL, lo que provocará la especulación más antigua. En este caso, la especulación anterior habrá almacenado en caché cualquier recurso que se pueda almacenar en caché HTTP para esa URL, por lo que la especulación más tiempo debería tener un costo reducido. Por este motivo, el límite se estableció en el mínimo umbral de 2. Las reglas de listas estáticas no se activan con una acción del usuario y, por lo tanto, tienen un límite más alto, ya que el navegador no puede saber cuáles y cuándo son necesarias.

Los límites immediate y eager también son dinámicos, por lo que quitar un elemento de secuencia de comandos de URL list creará capacidad mediante la cancelación de las especulaciones quitadas.

Chrome también evitará que se usen especulaciones en determinadas condiciones, entre las que se incluyen las siguientes:

  • Save-Data:
  • Ahorro de energía cuando está habilitada y con batería baja
  • Restricciones de memoria.
  • El parámetro de configuración “Precargar páginas” está desactivado (lo que también se desactiva de forma explícita con las extensiones de Chrome, como uBlock Origin).
  • Páginas abiertas en pestañas en segundo plano.

Chrome tampoco renderizará iframes de origen cruzado en páginas renderizadas previamente hasta la activación.

Todas estas condiciones tienen como objetivo reducir el impacto de la sobreespeculación cuando sería perjudicial para los usuarios.

Cómo incluir reglas de especulación en una página

Las reglas de especulación pueden incluirse de forma estática en el código HTML de la página o insertarse dinámicamente en la página con JavaScript:

  • Reglas de especulación incluidas de forma estática: Por ejemplo, un sitio de medios de comunicación o un blog pueden renderizar previamente el artículo más reciente si suele ser el próximo paso de navegación para una gran proporción de usuarios. De forma alternativa, se pueden usar reglas de documentos con un moderate o conservative para especular a medida que los usuarios interactúan con vínculos.
  • Reglas de especulación insertadas de forma dinámica: Estas reglas pueden basarse en la lógica de la aplicación, personalizarse para el usuario o basarse en otras heurísticas.

Se recomienda que aquellos que prefieran la inserción dinámica basada en acciones como colocar el cursor sobre un vínculo o hacer clic hacia abajo en un vínculo (como lo hicieron muchas bibliotecas en el pasado con <link rel=prefetch>) deben observar las reglas de los documentos, ya que permiten que el navegador controle muchos de tus casos de uso.

Se pueden agregar reglas de especulación en el <head> o el <body> del marco principal. No se aplican las reglas de especulación en los submarcos, y las reglas de especulación en las páginas renderizadas previamente solo se aplican una vez que se activa esa página.

El encabezado HTTP Speculation-Rules

Navegadores compatibles

  • 121
  • 121
  • x
  • x

Origen

Las reglas de especulación también se pueden entregar con un encabezado HTTP Speculation-Rules, en lugar de incluirlas directamente en el HTML del documento. Esto facilita la implementación de las CDN sin la necesidad de alterar el contenido de los documentos.

El encabezado HTTP Speculation-Rules se muestra con el documento y apunta a una ubicación de un archivo JSON que contiene las reglas de especulación:

Speculation-Rules: "/speculationrules.json"

Este recurso debe usar el tipo de MIME correcto y, si es un recurso de origen cruzado, pasar una verificación de CORS.

Content-Type: application/speculationrules+json
Access-Control-Allow-Origin: *

Si quieres usar URLs relativas, puedes incluir la clave "relative_to": "document" en tus reglas de especulación. De lo contrario, las URLs relativas estarán relacionadas con la URL del archivo JSON de las reglas de especulación. Esto puede ser particularmente útil si necesitas seleccionar algunos (o todos) vínculos del mismo origen.

Reglas de especulación y SPA

Las reglas de especulación solo son compatibles con las navegaciones de páginas completas administradas por el navegador, y no para las aplicaciones de una sola página (SPA) ni para las páginas del shell de la aplicación. Estas arquitecturas no usan recuperaciones de documentos, sino que realizan recuperaciones parciales de datos o páginas a través de la API, que luego se procesan y se presentan en la página actual. La app puede cargar previamente los datos necesarios para estas denominadas "navegaciones en segundo plano" fuera de las reglas de especulación, pero no se pueden renderizar previamente.

Las reglas de especulación se pueden usar para renderizar previamente la aplicación en sí desde una página anterior. Esto puede ayudar a compensar algunos de los costos adicionales de carga inicial que tienen algunos SPA. Sin embargo, los cambios de ruta dentro de la app no se pueden renderizar previamente.

Cómo depurar reglas de especulación

Consulta la publicación dedicada sobre cómo depurar reglas de especulación para conocer las nuevas funciones de las Herramientas para desarrolladores de Chrome que te ayudarán a ver y depurar esta nueva API.

Varias reglas de especulación

También se pueden agregar varias reglas de especulación a la misma página y se adjuntan a las reglas existentes. Por lo tanto, las siguientes maneras diferentes dan como resultado la renderización previa de one.html y two.html:

Lista de URLs:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html", "two.html"]
    }
  ]
}
</script>

Varias secuencias de comandos speculationrules:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    }
  ]
}
</script>
<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

Varias listas dentro de un conjunto de speculationrules

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    },
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

Navegadores compatibles

  • 121
  • 121
  • x
  • x

Origen

Cuando se realiza una carga previa o se renderiza previamente una página, es posible que ciertos parámetros de URL (técnicamente conocidos como parámetros de búsqueda) no tengan importancia para la página entregada por el servidor y que solo los use el código JavaScript del cliente.

Por ejemplo, Google Analytics utiliza los parámetros de UTM para las mediciones de una campaña, pero no suelen implicar que el servidor envíe diferentes páginas. Esto significa que page1.html?utm_content=123 y page1.html?utm_content=456 entregarán la misma página desde el servidor, por lo que se puede volver a usar la misma página desde la caché.

Del mismo modo, las aplicaciones pueden usar otros parámetros de URL que solo se manejan del lado del cliente.

La propuesta No-Vary-Search permite que un servidor especifique parámetros que no den lugar a una diferencia con el recurso entregado y, por lo tanto, permite que un navegador reutilice versiones previamente almacenadas en caché de un documento que solo difieren en estos parámetros. Esto es compatible con Chrome (y los navegadores basados en Chromium) para especulaciones de navegación con carga previa (aunque queremos admitir esto también para la renderización previa).

Las reglas de especulación admiten el uso de expects_no_vary_search para indicar dónde se espera que se muestre un encabezado HTTP No-Vary-Search. Esto puede ayudar a evitar más descargas innecesarias.

<script type="speculationrules">
{
  "prefetch": [{
    "urls": ["/products*"],
    "expects_no_vary_search": "params=(\"id\")"
  }]
}
</script>

<a href="/products?id=123">Product 123</a>
<a href="/products?id=124">Product 124</a>

En este ejemplo, el código HTML de la página inicial /products es el mismo para los IDs del producto 123 y 124. Sin embargo, el contenido de la página finalmente difiere en función de la renderización del cliente con JavaScript para recuperar datos de productos a través del parámetro de búsqueda id. Por lo tanto, precargamos esa URL con anticipación y deberíamos mostrar un encabezado HTTP No-Vary-Search que indique que la página se puede usar para cualquier parámetro de búsqueda id.

Sin embargo, si el usuario hace clic en cualquiera de los vínculos antes de que se complete la carga previa, es posible que el navegador no haya recibido la página /products. En este caso, el navegador no sabe si contendrá el encabezado HTTP No-Vary-Search. Luego, el navegador puede elegir si recuperar el vínculo de nuevo o esperar a que se complete la carga previa para ver si contiene un encabezado HTTP No-Vary-Search. La configuración expects_no_vary_search le permite al navegador saber que se espera que la respuesta de la página contenga un encabezado HTTP No-Vary-Search y esperar a que se complete esa carga previa.

Restricciones de las reglas de especulación y mejoras futuras

Las reglas de especulación se limitan a las páginas abiertas dentro de la misma pestaña, pero estamos trabajando para reducir esa restricción.

De forma predeterminada, las especulaciones se restringen a páginas del mismo origen. Especulaciones de páginas de origen cruzado en el mismo sitio (por ejemplo, https://a.example.com podría renderizar previamente una página en https://b.example.com). Para usar esta opción, la página especulada (en este ejemplo, https://b.example.com) debe habilitar la opción incluyendo un encabezado HTTP Supports-Loading-Mode: credentialed-prerender. De lo contrario, Chrome cancelará la especulación.

Es posible que las versiones futuras también permitan la renderización previa para páginas de origen cruzado que no sean del mismo sitio, siempre y cuando no existan cookies para la página renderizada previamente y esta se habilite con un encabezado HTTP Supports-Loading-Mode: uncredentialed-prerender similar.

Las reglas de especulación ya admiten cargas previas de origen cruzado, pero solo cuando no existen cookies para el dominio de origen cruzado. Si existen cookies del usuario que visitó ese sitio anteriormente, no se activará la especulación y se mostrará un error en Herramientas para desarrolladores.

Dadas esas limitaciones actuales, un patrón que puede mejorar las experiencias de los usuarios para los vínculos internos y externos cuando sea posible es renderizar previamente las URL del mismo origen y, luego, intentar cargar previamente las URLs de origen cruzado:

<script type="speculationrules">
  {
    "prerender": [
      {
        "where": { "href_matches": "/*" },
        "eagerness": "moderate"
      }
    ],
    "prefetch": [
      {
        "where": { "not": { "href_matches": "/*" } },
        "eagerness": "moderate"
      }
    ]
  }
</script>

Por motivos de seguridad, la restricción para evitar especulaciones de origen cruzado sobre vínculos de origen cruzado de forma predeterminada es necesaria. Es una mejora en comparación con <link rel="prefetch"> para destinos de origen cruzado que tampoco enviarán cookies, pero aún intentarán la carga previa, lo que generará una carga previa desperdiciada que se debe volver a enviar o, lo que es peor, una carga incorrecta de la página.

No se admiten las reglas de especulación para la carga previa de páginas controladas por service workers. Estamos trabajando para agregar esta compatibilidad. Sigue este problema de Service Worker de asistencia para ver las actualizaciones. Se admite la renderización previa para páginas controladas por service worker.

Detección de compatibilidad con la API de Speculation Rules

Puedes detectar la compatibilidad de la API de Speculation Rules con verificaciones HTML estándar:

if (HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')) {
  console.log('Your browser supports the Speculation Rules API.');
}

Agrega reglas de especulación de forma dinámica a través de JavaScript

Este es un ejemplo de cómo agregar una regla de especulación prerender con JavaScript:

if (HTMLScriptElement.supports &&
    HTMLScriptElement.supports('speculationrules')) {
  const specScript = document.createElement('script');
  specScript.type = 'speculationrules';
  specRules = {
    prerender: [
      {
        urls: ['/next.html'],
      },
    ],
  };
  specScript.textContent = JSON.stringify(specRules);
  console.log('added speculation rules to: next.html');
  document.body.append(specScript);
}

Puedes ver una demostración de la renderización previa de la API de Speculation Rules mediante la inserción de JavaScript en esta página de demostración de renderización previa.

Si insertas un elemento <script type = "speculationrules"> directamente en el DOM, no se registrarán las reglas de especulación, ya que se deben agregar como se mostró anteriormente. Por ejemplo, la edición directa del panel Elements en las Herramientas para desarrolladores de Chrome para agregar el elemento <script type = "speculationrules"> no registra las reglas de especulación, sino que la secuencia de comandos que agrega esto dinámicamente al DOM debe ejecutarse desde la consola para insertar las reglas.

Agrega reglas de especulación a través de un administrador de etiquetas

Para agregar reglas de especulación con un administrador de etiquetas, como Google Tag Manager (GTM), debes insertarlas a través de JavaScript, en lugar de agregar el elemento <script type = "speculationrules"> directamente a través de GTM por los mismos motivos que se mencionaron anteriormente:

Configuración de etiquetas HTML personalizadas en Google Tag Manager
Agrega reglas de especulación mediante Google Tag Manager.

Ten en cuenta que este ejemplo usa var, ya que GTM no admite const.

Cancelar reglas de especulación

Si quitas las reglas de especulación, se cancelará la renderización previa, pero, para el momento en que esto suceda, es probable que los recursos ya se hayan gastado para iniciar la renderización previa, por lo que se recomienda no realizarla si hay alguna probabilidad de que se deba cancelar.

Reglas de especulación y política de seguridad del contenido

Dado que las reglas de especulación usan un elemento <script>, aunque solo contengan JSON, deben incluirse en la Política de seguridad de contenido de script-src si el sitio lo usa, ya sea con un hash o nonce.

Se puede agregar un nuevo inline-speculation-rules a script-src, lo que permite que se admitan los elementos <script type="speculationrules"> inyectados desde hash o secuencias de comandos no cedidas. No admite reglas incluidas en el HTML inicial, por lo que JavaScript debe insertar las reglas para los sitios que usan una CSP estricta.

Cómo detectar e inhabilitar la renderización previa

La renderización previa suele ser una experiencia positiva para los usuarios, ya que permite una renderización rápida de la página, a menudo instantánea. Esto beneficia tanto al usuario como al propietario del sitio, ya que las páginas renderizadas previamente permiten una mejor experiencia del usuario que podría ser difícil de lograr de otra manera.

Sin embargo, puede haber casos en los que no quieras que se realice la renderización previa de las páginas, por ejemplo, cuando las páginas cambian de estado, ya sea en función de la solicitud inicial o de la ejecución de JavaScript en la página.

Cómo habilitar o inhabilitar la renderización previa en Chrome

La renderización previa solo está habilitada para los usuarios de Chrome con el parámetro de configuración "Precargar páginas" en chrome://settings/performance/. Además, la renderización previa también está inhabilitada en dispositivos con poca memoria o si el sistema operativo está en los modos de Ahorro de datos o Ahorro de energía. Consulta la sección Límites de Chrome.

Cómo detectar e inhabilitar la renderización previa del servidor

Las páginas renderizadas previamente se enviarán con el encabezado HTTP Sec-Purpose:

Sec-Purpose: prefetch;prerender

Las páginas precargadas con la API de Speculation Rules tendrán este encabezado establecido solo en prefetch:

Sec-Purpose: prefetch

Los servidores pueden responder en función de este encabezado para registrar solicitudes de especulación, mostrar contenido diferente o evitar que se realice una renderización previa. Si se muestra un código de respuesta no exitoso (es decir, no un 200 ni un 304), la página no se renderizará previamente y se descartará cualquier página con carga previa.

Si no quieres que una página específica se renderice previamente, esta es la mejor manera de asegurarte de que no suceda. Sin embargo, para ofrecer la mejor experiencia, se recomienda permitir la renderización previa y retrasar las acciones que deben ocurrir solo cuando se ve realmente la página mediante JavaScript.

Cómo detectar la renderización previa en JavaScript

La API de document.prerendering mostrará true mientras se realiza la renderización previa de la página. Las páginas pueden usarlo para evitar (o retrasar) ciertas actividades durante la renderización previa hasta que la página esté realmente activada.

Una vez que se active un documento renderizado previamente, también se establecerá el valor de activationStart de PerformanceNavigationTiming en una hora distinta de cero, que representa el tiempo entre el inicio de la renderización previa y la activación del documento.

Puedes usar una función para verificar las páginas con renderización previa y renderización previa, como las siguientes:

function pagePrerendered() {
  return (
    document.prerendering ||
    self.performance?.getEntriesByType?.('navigation')[0]?.activationStart > 0
  );
}

La forma más fácil de ver si una página se renderizó previamente (ya sea de forma total o parcial) es abrir las Herramientas para desarrolladores después de activar la página y escribir performance.getEntriesByType('navigation')[0].activationStart en la consola. Si se muestra un valor distinto de cero, sabrás que la página se renderizó previamente:

La consola en Herramientas para desarrolladores de Chrome muestra una activación positiva. El comienzo indica que la página se renderizó previamente.
Prueba la renderización previa en la consola.

Cuando el usuario que está viendo la página active la página, se enviará el evento prerenderingchange en document, que se puede usar para habilitar actividades que antes se iniciarían de forma predeterminada al cargar la página, pero que deseas retrasar hasta que el usuario vea la página.

Con estas APIs, el frontend de JavaScript puede detectar las páginas renderizadas previamente y tomar medidas al respecto de manera adecuada.

Impacto en las estadísticas

Analytics se usa para medir el uso del sitio web; por ejemplo, con Google Analytics para medir las vistas de páginas y los eventos. También puedes medir las métricas de rendimiento de las páginas con supervisión de usuarios reales (RUM).

Las páginas solo se deben renderizar previamente cuando haya una alta probabilidad de que el usuario cargue la página. Es por eso que las opciones de renderización previa de la barra de direcciones de Chrome solo ocurren cuando hay una probabilidad muy alta (superior al 80% de las veces).

Sin embargo, en especial cuando se usa la API de Speculation Rules, las páginas renderizadas previamente pueden tener un impacto en las estadísticas, y es posible que los propietarios de los sitios deban agregar código adicional para habilitar solo las estadísticas de las páginas que se renderizan previamente durante la activación, ya que no todos los proveedores de estadísticas pueden hacerlo de forma predeterminada.

Para ello, puedes usar un Promise que espera el evento prerenderingchange si se está renderizando un documento previamente o se resuelve de inmediato si se está realizando la siguiente acción:

// Set up a promise for when the page is activated,
// which is needed for prerendered pages.
const whenActivated = new Promise((resolve) => {
  if (document.prerendering) {
    document.addEventListener('prerenderingchange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenActivated;
  // Initialise your analytics
}

initAnalytics();

Un enfoque alternativo es retrasar las actividades analíticas hasta que la página sea visible por primera vez, lo que cubriría el caso de renderización previa y también cuando las pestañas se abren en segundo plano (por ejemplo, cuando haces clic con el botón derecho y se abren en una pestaña nueva):

// Set up a promise for when the page is first made visible
const whenFirstVisible = new Promise((resolve) => {
  if (document.hidden) {
    document.addEventListener('visibilitychange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenFirstVisible;
  // Initialise your analytics
}

initAnalytics();

Si bien esto puede tener sentido para Analytics y casos de uso similares, en otros casos, es posible que desees que se cargue más contenido para esos casos y que uses document.prerendering y prerenderingchange para segmentar específicamente páginas de renderización previa.

Cómo retener otro contenido durante la renderización previa

Se pueden usar las mismas APIs que se analizaron anteriormente para retener otro contenido durante la fase de renderización previa. Pueden ser partes específicas de JavaScript o elementos completos de secuencias de comandos que preferirías no ejecutar durante la etapa de renderización previa.

Por ejemplo, con esta secuencia de comandos:

<script src="https://example.com/app/script.js" async></script>

Puedes cambiar esto a un elemento de secuencia de comandos insertado de manera dinámica que solo se inserta en función de la función whenActivated anterior:

async function addScript(scriptUrl) {
  await whenActivated;
  const script = document.createElement('script');
  script.src = 'scriptUrl';
  document.body.appendChild(script);
}

addScript('https://example.com/app/script.js');

Esto puede ser útil para detener distintas secuencias de comandos que incluyan estadísticas, o bien para renderizar el contenido en función del estado o de otras variables que puedan cambiar durante una visita. Por ejemplo, las recomendaciones, el estado de acceso o los íconos de carrito de compras podrían retenerse para garantizar que se presente la información más actualizada.

Si bien es más probable que esto ocurra con más frecuencia cuando se usa la renderización previa, estas condiciones también se aplican a las páginas cargadas en las pestañas en segundo plano que se mencionaron anteriormente (por lo que se podría usar la función whenFirstVisible en lugar de whenActivated).

En muchos casos, lo ideal es que el estado también se verifique en los cambios generales de visibilitychange. Por ejemplo, cuando regresas a una página que está en segundo plano, los contadores de compras deben actualizarse con la cantidad más reciente de artículos en la cesta. Por lo tanto, este no es un problema específico de la renderización previa, pero esta solo hace que un problema existente sea más evidente.

Una forma en la que Chrome mitiga la necesidad de unir secuencias de comandos o funciones manualmente es que ciertas APIs se retienen, como se mencionó anteriormente, y además no se renderizan los iframes de terceros, por lo que solo el contenido adicional se debe retener de forma manual.

Cómo medir el rendimiento

Para medir las métricas de rendimiento, los análisis deben considerar si es mejor medirlas en función del tiempo de activación en lugar del tiempo de carga de la página que informarán las APIs del navegador.

En el caso de las Métricas web esenciales, que mide Chrome a través del Informe sobre la experiencia del usuario en Chrome, estos datos están destinados a medir la experiencia del usuario. por lo que se miden según el tiempo de activación. Esto suele dar como resultado un LCP de 0 segundos, por ejemplo, lo que demuestra que esta es una excelente manera de mejorar tus Métricas web esenciales.

A partir de la versión 3.1.0, se actualizó la biblioteca web-vitals para controlar las navegaciones renderizadas previamente de la misma manera que Chrome mide las Métricas web esenciales. Esta versión también marca las navegaciones renderizadas previamente para esas métricas en el atributo Metric.navigationType si la página se renderizó previamente de forma total o parcial.

Mide las renderizaciones previas

Si una página está renderizada previamente, se puede ver con una entrada activationStart de PerformanceNavigationTiming distinta de cero. Esto se puede registrar con una dimensión personalizada, o algo similar, cuando se registran las vistas de página, por ejemplo, con la función pagePrerendered que se describió anteriormente:

// Set Custom Dimension for Prerender status
gtag('set', { 'dimension1': pagePrerendered() });
// Initialise GA - including sending page view by default
gtag('config', 'G-12345678-1');

Esto permitirá que tus estadísticas muestren cuántas navegaciones se renderizan previamente en comparación con otros tipos de navegación, y también te permite correlacionar las métricas de rendimiento o las métricas empresariales con estos diferentes tipos de navegación. Tener páginas más rápidas significa que los usuarios estarán más satisfechos, lo que a menudo puede tener un impacto real en las mediciones de la empresa, como lo demuestran nuestros casos de éxito.

A medida que mides el impacto comercial de la renderización previa de páginas para navegaciones instantáneas, puedes decidir si vale la pena invertir más esfuerzo en el uso de esta tecnología para permitir que se rendericen más navegaciones previamente o investigar por qué las páginas no se renderizan previamente.

Mide las tasas de aciertos

Además de medir el impacto de las páginas que se visitan después de una renderización previa, es importante medir las páginas que se renderizan previamente y que no se visitan posteriormente. Esto podría implicar que realizas una gran cantidad de renderizaciones previas y que estás usando recursos valiosos del usuario para obtener pocos beneficios.

Esto se puede medir activando un evento de estadísticas cuando se insertan reglas de especulación (después de verificar que el navegador admite la renderización previa con HTMLScriptElement.supports('speculationrules')) para indicar que se solicitó la renderización previa. Ten en cuenta que el solo hecho de que se haya solicitado una renderización previa no indica que se haya iniciado o completado una renderización previa, como se indicó anteriormente, una renderización previa es una sugerencia para el navegador, y es posible que decida no renderizar previamente páginas en la configuración del usuario, el uso actual de la memoria ni otras heurísticas.

Luego, puedes comparar la cantidad de estos eventos con las vistas de página reales con renderización previa. O bien, activa otro evento durante la activación si eso facilita la comparación.

La "tasa de hits exitosos" se puede aproximar observando la diferencia entre estas dos cifras. En el caso de las páginas en las que usas la API de Speculation Rules para renderizar previamente las páginas, puedes ajustar las reglas de forma adecuada para asegurarte de mantener una tasa de hits alta y así mantener el equilibrio entre usar los recursos de los usuarios para ayudarlos y usarlos innecesariamente.

Ten en cuenta que es posible que algunas renderizaciones previas se realicen debido a la renderización previa de la barra de direcciones y no solo a tus reglas de especulación. Puedes verificar el document.referrer (que estará en blanco para la navegación por la barra de direcciones, incluidas las navegaciones renderizadas previamente en la barra de direcciones) si deseas diferenciarlas.

Recuerda también observar las páginas que no tienen renderizaciones previas, ya que esto podría indicar que no son aptas para la renderización previa, ni siquiera desde la barra de direcciones. Esto puede significar que no te beneficias de esta mejora de rendimiento. El equipo de Chrome quiere agregar herramientas adicionales para probar la elegibilidad de la renderización previa, similar a la herramienta de prueba bfcache, y también agregar una API para exponer por qué falló un procesamiento previo.

Impacto en las extensiones

Consulta la entrada dedicada a Extensiones de Chrome: Extensión de la API para admitir la navegación instantánea, donde se detallan algunas consideraciones adicionales que los autores de extensiones podrían tener en cuenta para las páginas renderizadas previamente.

Comentarios

El equipo de Chrome está desarrollando activamente la renderización previa, y hay muchos planes para ampliar el alcance de lo que está disponible en la versión 108 de Chrome. Agradecemos cualquier comentario sobre el repositorio de GitHub o sobre el uso de nuestra herramienta de seguimiento de errores, y esperamos escuchar y compartir casos de éxito de esta emocionante API nueva.

Agradecimientos

Miniatura de Marc-Olivier Jodoin en Unsplash