Reduce las cargas útiles de JavaScript con la división de código

A nadie le gusta esperar. Más del 50% de los usuarios abandonan un sitio web si tarda más de 3 segundos en cargarse.

El envío de cargas útiles de JavaScript grandes afecta la velocidad de tu sitio de manera significativa. En lugar de enviar todo el código JavaScript al usuario en cuanto se carga la primera página de la aplicación, divide el paquete en varias partes y envía solo lo necesario al principio.

La división de código es una técnica que busca minimizar el tiempo de inicio. Cuando enviamos menos JavaScript al inicio, podemos lograr que las aplicaciones sean más interactivas más rápido minimizando el trabajo del subproceso principal durante este período crítico.

En el caso de las Métricas web esenciales, reducir las cargas útiles de JavaScript que se descargan durante el inicio contribuirá a mejorar los tiempos de Interaction to Next Paint (INP). El razonamiento detrás de esto es que, cuando se libera el subproceso principal, la aplicación puede responder a las entradas del usuario más rápido, ya que reduce los costos de inicio relacionados con el análisis, la compilación y la ejecución de JavaScript.

Según la arquitectura de tu sitio web, en particular, si depende en gran medida del procesamiento del cliente, reducir el tamaño de las cargas útiles de JavaScript responsables de renderizar el marcado puede mejorar los tiempos de Largest Contentful Paint (LCP). Esto puede ocurrir cuando el navegador demora en descubrir el recurso de LCP hasta que se completa el marcado del cliente o cuando el subproceso principal está demasiado ocupado para renderizar ese elemento de LCP. Ambas situaciones pueden retrasar el tiempo de LCP de la página.

Medir

Lighthouse muestra una auditoría fallida cuando se demora una cantidad significativa de tiempo en ejecutar todo el código JavaScript de una página.

Una auditoría de Lighthouse fallida que muestra que las secuencias de comandos tardan demasiado en ejecutarse.

Divide el paquete de JavaScript para enviar solo el código necesario para la ruta inicial cuando el usuario cargue una aplicación. Esto minimiza la cantidad de secuencias de comandos que se deben analizar y compilar, lo que genera tiempos de carga de páginas más rápidos.

Los agrupadores de módulos populares, como webpack, Parcel y Rollup, te permiten dividir tus paquetes con importaciones dinámicas. Por ejemplo, considera el siguiente fragmento de código que muestra un ejemplo de un método someFunction que se activa cuando se envía un formulario.

import moduleA from "library";

form
.addEventListener("submit", e => {
  e
.preventDefault();
  someFunction
();
});

const someFunction = () => {
 
// uses moduleA
}

Aquí, someFunction usa un módulo importado de una biblioteca en particular. Si este módulo no se usa en ningún otro lugar, se puede modificar el bloque de código para usar una importación dinámica para recuperarlo solo cuando el usuario envíe el formulario.

form.addEventListener("submit", e => {
  e
.preventDefault();
 
import('library.moduleA')
   
.then(module => module.default) // using the default export
   
.then(() => someFunction())
   
.catch(handleError());
});

const someFunction = () => {
   
// uses moduleA
}

El código que compone el módulo no se incluye en el paquete inicial y ahora se carga de forma diferida o se proporciona al usuario solo cuando es necesario después del envío del formulario. Para mejorar aún más el rendimiento de la página, precarga fragmentos críticos para priorizarlos y recuperarlos antes.

Si bien el fragmento de código anterior es un ejemplo simple, la carga diferida de dependencias de terceros no es un patrón común en aplicaciones más grandes. Por lo general, las dependencias de terceros se dividen en un paquete de proveedores independiente que se puede almacenar en caché, ya que no se actualizan con tanta frecuencia. Puedes obtener más información sobre cómo SplitChunksPlugin puede ayudarte a hacerlo.

La división a nivel de la ruta o del componente cuando se usa un framework del cliente es un enfoque más simple para la carga diferida de diferentes partes de tu aplicación. Muchos frameworks populares que usan webpack proporcionan abstracciones para que la carga diferida sea más fácil que sumergirse en las configuraciones por tu cuenta.