Precarga los recursos críticos para mejorar la velocidad de carga

Cuando abres una página web, el navegador solicita el documento HTML a un servidor, analiza su contenido y envía solicitudes independientes para cualquier recurso al que se haga referencia. Como desarrollador, ya conoces todos los recursos que necesita tu página y cuáles son los más importantes. Puedes usar ese conocimiento para solicitar los recursos críticos con anticipación y acelerar el proceso de carga. En esta publicación, se explica cómo lograrlo con <link rel="preload">.

Cómo funciona la precarga

La carga previa es más adecuada para los recursos que el navegador suele descubrir tarde.

Captura de pantalla del panel Network de Herramientas para desarrolladores de Chrome.
En este ejemplo, la fuente Pacifico se define en la hoja de diseño con una regla @font-face. El navegador carga el archivo de fuente solo después de que termina de descargar y analizar la hoja de estilo.

Cuando precargas un recurso determinado, le indicas al navegador que deseas recuperarlo antes de que lo descubra por su cuenta, ya que tienes la certeza de que es importante para la página actual.

Captura de pantalla del panel de red de Chrome DevTools después de aplicar la carga previa.
En este ejemplo, la fuente Pacifico se precarga, por lo que la descarga se realiza en paralelo con la hoja de estilo.

La cadena de solicitudes críticas representa el orden de los recursos que el navegador prioriza y recupera. Lighthouse identifica los recursos que se encuentran en el tercer nivel de esta cadena como descubiertos tarde. Puedes usar la auditoría Carga previa de solicitudes de claves para identificar qué recursos cargar previamente.

Es la auditoría de Lighthouse sobre la precarga de solicitudes de claves.

Puedes precargar recursos agregando una etiqueta <link> con rel="preload" al encabezado de tu documento HTML:

<link rel="preload" as="script" href="critical.js">

El navegador almacena en caché los recursos precargados para que estén disponibles de inmediato cuando se necesiten. (No ejecuta las secuencias de comandos ni aplica las hojas de estilo).

Las sugerencias de recursos, por ejemplo, preconnect y prefetch, se ejecutan según lo considere adecuado el navegador. Por otro lado, el preload es obligatorio para el navegador. Los navegadores modernos ya son bastante buenos para priorizar recursos, por lo que es importante usar preload con moderación y solo precargar los recursos más críticos.

Las precargas no utilizadas activan una advertencia de la consola en Chrome, aproximadamente 3 segundos después del evento load.

Advertencia de la consola de Herramientas para desarrolladores de Chrome sobre recursos precargados sin usar.

Casos de uso

Precarga de recursos definidos en CSS

Las fuentes definidas con reglas @font-face o las imágenes de fondo definidas en archivos CSS no se descubren hasta que el navegador descarga y analiza esos archivos CSS. La precarga de estos recursos garantiza que se recuperen antes de que se descarguen los archivos CSS.

Precarga de archivos CSS

Si usas el enfoque de CSS crítico, divides tu CSS en dos partes. El CSS crítico necesario para renderizar el contenido de la mitad superior de la página se intercala en el <head> del documento, y el CSS no crítico suele cargarse de forma diferida con JavaScript. Esperar a que se ejecute JavaScript antes de cargar CSS no críticos puede causar demoras en la renderización cuando los usuarios se desplazan, por lo que es una buena idea usar <link rel="preload"> para iniciar la descarga antes.

Precarga de archivos JavaScript

Dado que los navegadores no ejecutan los archivos precargados, la precarga es útil para separar la recuperación de la ejecución, lo que puede mejorar métricas como el tiempo hasta la interactividad. La precarga funciona mejor si divides tus paquetes de JavaScript y solo precargas los fragmentos críticos.

Cómo implementar rel=preload

La forma más sencilla de implementar preload es agregar una etiqueta <link> al <head> del documento:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

Proporcionar el atributo as ayuda al navegador a establecer la prioridad del recurso prefetch según su tipo, establecer los encabezados correctos y determinar si el recurso ya existe en la caché. Los valores aceptados para este atributo incluyen: script, style, font, image y otros.

Algunos tipos de recursos, como las fuentes, se cargan en modo anónimo. Para esos, debes establecer el atributo crossorigin con preload:

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

Los elementos <link> también aceptan un atributo type, que contiene el tipo de MIME del recurso vinculado. Los navegadores usan el valor del atributo type para asegurarse de que los recursos se carguen previamente solo si se admite su tipo de archivo. Si un navegador no admite el tipo de recurso especificado, ignorará el <link rel="preload">.

También puedes cargar previamente cualquier tipo de recurso a través del encabezado HTTP Link:

Link: </css/style.css>; rel="preload"; as="style"

Un beneficio de especificar preload en el encabezado HTTP es que el navegador no necesita analizar el documento para descubrirlo, lo que puede ofrecer pequeñas mejoras en algunos casos.

Precarga de módulos de JavaScript con webpack

Si usas un bundler de módulos que crea archivos de compilación de tu aplicación, debes verificar si admite la inserción de etiquetas de precarga. Con webpack versión 4.6.0 o posterior, la carga previa se admite a través del uso de comentarios mágicos dentro de import():

import(_/* webpackPreload: true */_ "CriticalChunk")

Si usas una versión anterior de webpack, usa un complemento de terceros, como preload-webpack-plugin.

Efectos de la carga previa en las Métricas web esenciales

La precarga es una potente optimización del rendimiento que afecta la velocidad de carga. Estas optimizaciones pueden generar cambios en las métricas web esenciales de tu sitio, por lo que es importante que los conozcas.

Largest Contentful Paint (LCP)

La precarga tiene un efecto poderoso en el Largest Contentful Paint (LCP) cuando se trata de fuentes e imágenes, ya que tanto las imágenes como los nodos de texto pueden ser candidatos a LCP. Las imágenes de héroe y las grandes cantidades de texto renderizadas con fuentes web pueden beneficiarse significativamente de una sugerencia de precarga bien ubicada, y se deben usar cuando haya oportunidades para entregar estos fragmentos importantes de contenido al usuario más rápido.

Sin embargo, debes tener cuidado cuando se trata de la precarga y otras optimizaciones. En particular, evita la carga previa de demasiados recursos. Si se priorizan demasiados recursos, en realidad no se prioriza ninguno. Los efectos de las sugerencias de precarga excesivas serán especialmente perjudiciales para los usuarios con redes más lentas, en las que la contención del ancho de banda será más evidente.

En su lugar, enfócate en algunos recursos valiosos que sabes que se beneficiarán de una precarga bien ubicada. Cuando precargues fuentes, asegúrate de publicarlas en formato WOFF 2.0 para reducir el tiempo de carga de recursos lo más posible. Dado que WOFF 2.0 tiene una excelente compatibilidad con los navegadores, usar formatos más antiguos, como WOFF 1.0 o TrueType (TTF), retrasará tu LCP si el candidato a LCP es un nodo de texto.

En lo que respecta al LCP y JavaScript, deberás asegurarte de enviar un marcado completo desde el servidor para que el analizador de precarga del navegador funcione correctamente. Si publicas una experiencia que depende por completo de JavaScript para renderizar el lenguaje de marcado y no puedes enviar HTML renderizado por el servidor, sería ventajoso intervenir donde el escáner de precarga del navegador no puede hacerlo y precargar los recursos que, de otro modo, solo se podrían descubrir cuando JavaScript termine de cargarse y ejecutarse.

Cumulative Layout Shift (CLS)

El cambio de diseño acumulado (CLS) es una métrica especialmente importante en lo que respecta a las fuentes web, y tiene una interacción significativa con las fuentes web que usan la propiedad font-display de CSS para administrar cómo se cargan las fuentes. Para minimizar los cambios de diseño relacionados con las fuentes web, considera las siguientes estrategias:

  1. Precarga las fuentes mientras usas el valor predeterminado block para font-display. Este es un equilibrio delicado. Bloquear la visualización de fuentes sin una alternativa se puede considerar un problema de experiencia del usuario. Por un lado, cargar fuentes con font-display: block; elimina los cambios de diseño relacionados con las fuentes web. Por otro lado, si las fuentes web son fundamentales para la experiencia del usuario, querrás que se carguen lo antes posible. Combinar una carga previa con font-display: block; puede ser una solución aceptable.
  2. Precarga fuentes mientras usas el valor fallback para font-display. fallback es un punto intermedio entre swap y block, ya que tiene un período de bloqueo extremadamente corto.
  3. Usa el valor optional para font-display sin carga previa. Si una fuente web no es fundamental para la experiencia del usuario, pero se usa para renderizar una cantidad significativa de texto de la página, considera usar el valor optional. En condiciones adversas, optional mostrará el texto de la página en una fuente de resguardo mientras carga la fuente en segundo plano para la siguiente navegación. El resultado neto en estas condiciones es un CLS mejorado, ya que las fuentes del sistema se renderizarán de inmediato, mientras que las cargas de páginas posteriores cargarán la fuente de inmediato sin cambios de diseño.

El CLS es una métrica difícil de optimizar cuando se trata de fuentes web. Como siempre, experimenta en el laboratorio, pero confía en tus datos de campo para determinar si tus estrategias de carga de fuentes mejoran el CLS o lo empeoran.

Interaction to Next Paint (INP)

La métrica Interaction to Next Paint mide la capacidad de respuesta a las entradas del usuario. Dado que la mayor parte de la interactividad en la Web se basa en JavaScript, precargar el código JavaScript que impulsa las interacciones importantes puede ayudar a mantener un INP más bajo en la página. Sin embargo, ten en cuenta que la precarga de demasiado JavaScript durante el inicio puede tener consecuencias negativas no deseadas si demasiados recursos compiten por el ancho de banda.

También deberás tener cuidado con la forma en que realizas la división del código. La división de código es una excelente optimización para reducir la cantidad de JavaScript que se carga durante el inicio, pero las interacciones pueden retrasarse si dependen de JavaScript que se carga justo al comienzo de la interacción. Para compensar esto, deberás examinar la intención del usuario y, luego, insertar una precarga para los fragmentos de JavaScript necesarios antes de que se produzca la interacción. Un ejemplo podría ser la carga previa del código JavaScript necesario para validar el contenido de un formulario cuando se enfoca cualquiera de los campos del formulario.

Conclusión

Para mejorar la velocidad de la página, precarga los recursos importantes que el navegador descubre tarde. Precargar todo sería contraproducente, por lo que debes usar preload con moderación y medir el impacto en el mundo real.