Codelab: Carga previamente recursos críticos para mejorar la velocidad de carga

En este codelab, se mejorará el rendimiento de la siguiente página web mediante la precarga y la carga previa de algunos recursos:

Captura de pantalla de la app

Medir

Primero, mide el rendimiento del sitio web antes de agregar optimizaciones.

  • Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa pantalla completa.

Ejecuta la auditoría de rendimiento de Lighthouse (Lighthouse > Options > Performance) en la versión publicada de tu Glitch (consulta también Descubre oportunidades de rendimiento con Lighthouse).

Lighthouse muestra la siguiente auditoría con errores para un recurso que se recupera con retraso:

Lighthouse: Precarga una auditoría de solicitudes de claves
  • Presiona "Control + Mayús + J" (o bien "Comando + Opción + J" en Mac) para abrir Herramientas para desarrolladores.
  • Haga clic en la pestaña Red.
Panel Network con recursos de descubrimiento tardío

El archivo main.css no se recupera con un elemento de vínculo (<link>) colocado en el documento HTML, pero un archivo JavaScript independiente, fetch-css.js, adjunta el elemento de vínculo al DOM después del evento window.onLoad. Esto significa que el archivo solo se recupera después de que el navegador termina de analizar y ejecutar el archivo JS. Del mismo modo, una fuente web (K2D.woff2) especificada en main.css solo se recupera una vez que el archivo CSS termina de descargarse.

La cadena de solicitudes críticas representa el orden de los recursos que el navegador prioriza y recupera. Actualmente, esta página web se ve de la siguiente manera:

├─┬ / (initial HTML file)
  └── fetch-css.js
    └── main.css
      └── K2D.woff2

Como el archivo CSS se encuentra en el tercer nivel de la cadena de solicitudes, Lighthouse lo identificó como un recurso de descubrimiento tardío.

Precarga los recursos críticos

El archivo main.css es un recurso fundamental que se necesita de inmediato en cuanto se carga la página. En el caso de archivos importantes como este recurso que se recuperan tarde en tu aplicación, usa una etiqueta de precarga de vínculo para indicarle al navegador que lo descargue antes. Para ello, agrega un elemento de vínculo al encabezado del documento.

Agrega una etiqueta de precarga para esta aplicación:

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
</head>

El atributo as se usa para identificar qué tipo de recurso se recupera, y as="style" se usa para precargar archivos de hojas de estilo.

Vuelve a cargar la aplicación y consulta el panel Red en Herramientas para desarrolladores.

Panel de red con recurso precargado

Observa cómo el navegador recupera el archivo CSS antes de que haya terminado de analizarse el código JavaScript responsable de su recuperación. Con la carga previa, el navegador sabe realizar una recuperación preventiva para el recurso, con el supuesto de que es fundamental para la página web.

Si no se usa correctamente, la precarga puede afectar el rendimiento mediante solicitudes innecesarias de recursos que no se usan. En esta aplicación, details.css es otro archivo CSS ubicado en la raíz del proyecto, pero se usa para otro /details route. Para mostrar un ejemplo de cómo se puede usar la precarga de manera incorrecta, también agrega una sugerencia de precarga para este recurso.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Vuelve a cargar la aplicación y observa el panel Red. Se realiza una solicitud para recuperar details.css, aunque la página web no lo esté usando.

Panel de red con carga previa innecesaria

Chrome muestra una advertencia en el panel de la consola cuando la página no usa un recurso precargado unos segundos después de que se carga.

Advertencia de precarga en la consola

Usa esta advertencia como indicador para identificar si tienes recursos precargados que tu página web no esté usando de inmediato. Ahora puedes quitar el vínculo de precarga innecesario para esta página.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Para obtener una lista de todos los tipos de recursos que se pueden recuperar junto con los valores correctos que deben usarse para el atributo as, consulta el artículo MDN sobre precarga.

Solicitar recursos futuros previamente

Carga previa es otra sugerencia del navegador que se puede usar para realizar una solicitud de un recurso que se usa en una ruta de navegación diferente, pero con una prioridad menor que la de otros recursos importantes necesarios para la página actual.

En este sitio web, si haces clic en la imagen, accederás a una ruta details/ independiente.

Ruta de detalles

Un archivo CSS independiente, details.css, contiene todos los estilos necesarios para esta página simple. Agrega un elemento de vínculo a index.html para realizar una carga previa de este recurso.

<head>
  <!-- ... -->
  <link rel="prefetch" href="details.css">
</head>

Para comprender cómo esto activa una solicitud para el archivo, abre el panel Red en Herramientas para desarrolladores y desmarca la opción Inhabilitar caché.

Inhabilitar la caché en las Herramientas para desarrolladores de Chrome

Vuelve a cargar la aplicación y observa que se realiza una solicitud de prioridad muy baja para details.css después de que se recuperan todos los demás archivos.

Panel de red con recurso cargado previamente

Con las Herramientas para desarrolladores abiertas, haz clic en la imagen del sitio web para navegar a la página details. Como se usa un elemento de vínculo en details.html para recuperar details.css, se realiza una solicitud para el recurso como se espera.

Solicitudes de red de la página de detalles

Haz clic en la solicitud de red details.css en Herramientas para desarrolladores para ver sus detalles. Notarás que el archivo se recupera de la caché de disco del navegador.

Solicitud de detalles recuperada de la caché del disco

Aprovechando el tiempo de inactividad del navegador, la carga previa realiza una solicitud anticipada de un recurso necesario para una página diferente. Esto acelera las solicitudes de navegación futuras, ya que permite que el navegador almacene en caché el recurso más rápido y lo entregue desde la caché cuando sea necesario.

Precarga y carga previa con webpack

En la publicación Reduce las cargas útiles de JavaScript con la división de código, se explora el uso de importaciones dinámicas para dividir un paquete en varios fragmentos. Esto se demuestra con una aplicación simple que importa de forma dinámica un módulo desde Lodash cuando se envía un formulario.

App de Clasificador mágico que muestra la división de código

Puedes acceder a la falla de esta solicitud aquí.

El siguiente bloque de código, que se encuentra en src/index.js,, es responsable de importar de forma dinámica el método cuando se hace clic en el botón.

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

Dividir un paquete mejora los tiempos de carga de la página, ya que reduce su tamaño inicial. La versión 4.6.0 de webpack proporciona compatibilidad para cargar previamente o previamente fragmentos que se importan de forma dinámica. Con esta aplicación como ejemplo, el método lodash se puede cargar previamente en el tiempo de inactividad del navegador; cuando un usuario presiona el botón, no hay demora para que se recupere el recurso.

Usa el parámetro de comentario webpackPrefetch específico dentro de una importación dinámica para cargar un fragmento en particular con anticipación. Así es como se vería con esta aplicación en particular.

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

Una vez que se vuelve a cargar la aplicación, webpack inserta una etiqueta de carga previa para el recurso en el encabezado del documento. Esto se puede ver en el panel Elements de Herramientas para desarrolladores.

Panel de elementos con etiqueta de carga previa

Observar las solicitudes en el panel Network (Red) también muestra que este fragmento se recupera con una prioridad baja después de que se solicitaron todos los demás recursos.

Panel de red con solicitud precargada

Si bien la carga previa tiene más sentido para este caso de uso, webpack también admite la precarga de fragmentos que se importan de forma dinámica.

import(/* webpackPreload: true */ 'module')

Conclusión

Con este codelab, comprenderás bien cómo la precarga o la carga previa de ciertos elementos pueden mejorar la experiencia del usuario en tu sitio. Es importante mencionar que estas técnicas no deben utilizarse para todos los recursos y usarlas de forma incorrecta puede perjudicar el rendimiento. Los mejores resultados se observan solo con la precarga o la carga previa de manera selectiva.

En síntesis:

  • Usa la precarga para los recursos que se descubren tarde, pero que son fundamentales para la página actual.
  • Usa la carga previa para los recursos que se necesitan para una ruta de navegación o una acción del usuario futuras.

Actualmente, no todos los navegadores admiten la precarga y la carga previa. Esto significa que no todos los usuarios de tu aplicación podrían notar mejoras en el rendimiento.

Si quieres obtener más información sobre aspectos específicos de cómo la precarga y la carga previa pueden afectar tu página web, consulta estos artículos: