Precarga recursos para acelerar la navegación en el futuro

Obtén información sobre la sugerencia de recursos rel=prefetch y cómo usarla.

Las investigaciones demuestran que los tiempos de carga más rápidos generan porcentajes de conversiones más altos y mejores experiencias del usuario. Si tienes estadísticas sobre cómo los usuarios se desplazan por tu sitio web y qué páginas es probable que visiten a continuación, puedes mejorar los tiempos de carga de las navegaciones futuras descargando los recursos de esas páginas con anticipación.

En esta guía, se explica cómo lograrlo con <link rel=prefetch>, una sugerencia de recursos que te permite implementar la precarga de forma fácil y eficiente.

Si agregas <link rel=prefetch> a una página web, le indicas al navegador que descargue páginas completas o algunos de los recursos (como secuencias de comandos o archivos CSS) que el usuario podría necesitar en el futuro:

<link rel="prefetch" href="/articles/" as="document">

Diagrama que muestra cómo funciona la precarga de vínculos.

La sugerencia prefetch consume bytes adicionales para los recursos que no se necesitan de inmediato, por lo que esta técnica debe aplicarse con cuidado. Solo realiza la precarga de recursos cuando tengas la certeza de que los usuarios los necesitarán. Considera no realizar la carga previa cuando los usuarios tengan conexiones lentas. Puedes detectarlo con la API de Network Information.

Existen diferentes formas de determinar qué vínculos se deben recuperar previamente. La más sencilla es la de recuperar previamente el primer vínculo o los primeros vínculos de la página actual. También hay bibliotecas que usan enfoques más sofisticados, que se explican más adelante en esta publicación.

Casos de uso

Carga previa de páginas posteriores

Precarga documentos HTML cuando las páginas posteriores sean predecibles, de modo que, cuando se haga clic en un vínculo, la página se cargue de inmediato.

Por ejemplo, en una página de ficha de producto, puedes obtener la página del producto más popular de la lista de antemano. En algunos casos, es aún más fácil anticipar la siguiente navegación. En una página de carrito de compras, la probabilidad de que un usuario visite la página de confirmación de la compra suele ser alta, lo que la convierte en una buena opción para la carga previa.

Si bien la precarga de recursos usa ancho de banda adicional, puede mejorar la mayoría de las métricas de rendimiento. El tiempo hasta el primer byte (TTFB) suele ser mucho más bajo, ya que la solicitud del documento genera un acierto de caché. Debido a que el TTFB será más bajo, las métricas posteriores basadas en el tiempo también suelen ser más bajas, incluidas Largest Contentful Paint (LCP) y First Contentful Paint (FCP).

Obtención anticipada de recursos estáticos

Precarga recursos estáticos, como secuencias de comandos o hojas de estilo, cuando se puedan predecir las secciones posteriores que podría visitar el usuario. Esto es muy útil cuando esos recursos se comparten en muchas páginas.

Por ejemplo, Netflix aprovecha el tiempo que los usuarios pasan en las páginas sin haber accedido a sus cuentas para realizar la carga previa de React, que se usará una vez que los usuarios accedan a sus cuentas. Gracias a esto, redujeron el tiempo de carga en un 30% para las navegaciones futuras.

El efecto de la carga previa de recursos estáticos en las métricas de rendimiento depende del recurso que se carga de forma previa:

  • La precarga de imágenes puede reducir significativamente los tiempos de LCP para los elementos de imagen de LCP.
  • La precarga de hojas de estilo puede mejorar el FCP y el LCP, ya que se eliminará el tiempo de red para descargar la hoja de estilo. Dado que los diseños de página bloquean la renderización, pueden reducir el LCP cuando se precargan. En los casos en que el elemento LCP de la página posterior sea una imagen de fondo CSS solicitada a través de la propiedad background-image, la imagen también se precargará como un recurso dependiente de la hoja de estilo precargada.
  • La recuperación anticipada de JavaScript permitirá que el procesamiento de la secuencia de comandos recuperada anticipadamente se realice mucho antes que si la red tuviera que recuperarla primero durante la navegación. Esto puede afectar la Interaction to Next Paint (INP) de una página. En los casos en que el marcado se renderiza en el cliente a través de JavaScript, se puede mejorar el LCP reduciendo los retrasos en la carga de recursos, y la renderización del marcado del cliente que contiene el elemento LCP de una página puede ocurrir antes.
  • La precarga de fuentes web que la página actual aún no usa puede eliminar los cambios de diseño. En los casos en que se usa font-display: swap;, se elimina el período de intercambio de la fuente, lo que genera una renderización más rápida del texto y elimina los cambios de diseño. Si una página futura usa la fuente recuperada previamente y el elemento de LCP de la página es un bloque de texto que usa una fuente web, la LCP de ese elemento también será más rápida.

Carga previa de fragmentos de JavaScript a pedido

La división de código de tus paquetes de JavaScript te permite cargar inicialmente solo partes de una app y cargar el resto de forma diferida. Si usas esta técnica, puedes aplicar la carga previa a las rutas o los componentes que no son necesarios de inmediato, pero que es probable que se soliciten pronto.

Por ejemplo, si tienes una página que contiene un botón que abre un cuadro de diálogo que contiene un selector de emojis, puedes dividirlo en tres fragmentos de JavaScript: principal, diálogo y selector. La pantalla principal y el diálogo se podían cargar inicialmente, mientras que el selector se podía cargar a pedido. Herramientas como webpack te permiten indicarle al navegador que realice la carga previa de estos fragmentos a pedido.

Cómo implementar rel=prefetch

La forma más sencilla de implementar prefetch es agregar una etiqueta <link> a la <head> del documento:

<head>
  ...
  <link rel="prefetch" href="/articles/" as="document">
  ...
</head>

El atributo as ayuda al navegador a establecer los encabezados correctos y determinar si el recurso ya está en la caché. Algunos valores de ejemplo para este atributo son: document, script, style, font, image y otros.

También puedes iniciar la precarga a través del encabezado HTTP Link:

Link: </css/style.css>; rel=prefetch

Un beneficio de especificar una sugerencia de carga previa en el encabezado HTTP es que el navegador no necesita analizar el documento para encontrar la sugerencia de recursos, lo que puede ofrecer pequeñas mejoras en algunos casos.

Cómo realizar la precarga de módulos de JavaScript con comentarios mágicos de webpack

Webpack te permite recuperar previamente las secuencias de comandos para las rutas o funciones que crees que los usuarios visitarán o usarán pronto.

En el siguiente fragmento de código, se carga de forma diferida una funcionalidad de ordenamiento de la biblioteca lodash para ordenar un grupo de números que se enviará mediante un formulario:

form.addEventListener("submit", e => {
  e.preventDefault()
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

En lugar de esperar a que se produzca el evento "enviar" para cargar esta funcionalidad, puedes recuperar este recurso de antemano para aumentar las probabilidades de que esté disponible en la caché cuando el usuario envíe el formulario. webpack permite hacerlo con los comentarios mágicos dentro de import():

form.addEventListener("submit", e => {
   e.preventDefault()
   import(/* webpackPrefetch: true */ 'lodash.sortby')
         .then(module => module.default)
         .then(sortInput())
         .catch(err => { alert(err) });
});

Esto le indica a webpack que inserte la etiqueta <link rel="prefetch"> en el documento HTML:

<link rel="prefetch" as="script" href="1.bundle.js">

Los beneficios de rendimiento de la precarga de fragmentos a pedido son un poco más complejos, pero, en términos generales, es posible que observes respuestas más rápidas a las interacciones que dependen de esos fragmentos a pedido, ya que estarán disponibles de inmediato. Según la naturaleza de la interacción, esto podría beneficiar al INP de una página.

La precarga en general también influye en la priorización de recursos general. Cuando se precarga un recurso, se hace con la prioridad más baja posible. Por lo tanto, los recursos cargados previamente no competirán por el ancho de banda de los recursos que necesita la página actual.

También puedes implementar una precarga más inteligente con bibliotecas que usan prefetch en segundo plano:

Tanto quicklink como Guess.js usan la API de Network Information para evitar la carga previa si un usuario está en una red lenta o tiene activada Save-Data.

Funcionamiento interno de la carga previa

Las sugerencias de recursos no son instrucciones obligatorias, y depende del navegador decidir si se ejecutan y cuándo.

Puedes usar la carga previa varias veces en la misma página. El navegador pone en cola todas las sugerencias y solicita cada recurso cuando está inactivo. En Chrome, si no se terminó de cargar una carga previa y el usuario navega al recurso de carga previa de destino, el navegador detecta la carga en curso como la navegación (otros proveedores de navegadores pueden implementar esto de manera diferente).

La carga previa se realiza con la prioridad "Más baja", por lo que los recursos cargados previamente no compiten por el ancho de banda con los recursos necesarios en la página actual.

Los archivos almacenados previamente se almacenan en la caché HTTP o en la caché de memoria (según si el recurso se puede almacenar en caché o no) durante un período que varía según el navegador. Por ejemplo, en Chrome, los recursos se conservan durante cinco minutos, después de los cuales se aplican las reglas normales de Cache-Control para el recurso.

Conclusión

El uso de prefetch puede mejorar en gran medida los tiempos de carga de las navegaciones futuras y hasta hacer que las páginas parezcan cargarse al instante. prefetch es ampliamente compatible con los navegadores modernos, lo que lo convierte en una técnica atractiva para mejorar la experiencia de navegación de muchos usuarios. Esta técnica requiere cargar bytes adicionales que podrían no usarse, así que ten cuidado cuando la uses. Solo hazlo cuando sea necesario y, de preferencia, solo en redes rápidas.