Cargar toda la lógica de una aplicación web desde el primer momento es uno de los errores más comunes que afectan el rendimiento. Cuando una librería solo se necesita tras la interacción del usuario, mantenerla dentro del bundle principal es un desperdicio de recursos. Aquí se explica paso a paso cómo extraer una dependencia y cargarla de forma perezosa usando las capacidades nativas de webpack.
¿Cómo se identificó el problema en el bundle principal?
Antes de optimizar, se resolvió un typo que impedía reproducir el video dentro del modal. En el archivo open-modal.js, el dataset esperado por la librería no era videoID sino VIDEO en mayúsculas seguido de ID [1:08]. Un detalle mínimo que bloqueaba toda la funcionalidad.
Con el modal funcionando, se analizó el empaquetado en modo de producción ejecutando npm run build y luego el servidor en el puerto 5000. El resultado mostraba dos archivos: vendors y main.bundle [2:05]. Al inspeccionar con el bundle analyzer, la librería modal-video aparecía empaquetada dentro del bundle principal de vendors. Esto significa que cada visitante descargaba esa librería aunque jamás hiciera clic en el botón de reproducir.
La conclusión fue clara: modal-video es totalmente innecesaria para la carga inicial de la página y solo se requiere en el instante en que el usuario presiona play [2:42].
¿Cómo funciona el lazy loading con la sintaxis import de webpack?
Webpack permite cargar módulos de forma perezosa mediante imports dinámicos, que devuelven una promesa. En lugar de importar la librería al inicio del archivo, se mueve la importación dentro del bloque del event listener que detecta el clic [3:15].
La sintaxis es directa:
javascript
import(/* webpackChunkName: "modal" */ './open-modal').then(({ openModal }) => {
openModal(videoID);
});
- Se elimina el
import estático del inicio del archivo.
- Se usa
import() como función que retorna una promesa.
- Al resolverse, webpack entrega el módulo completo; como
openModal es un named export, se aplica destructuring de JavaScript para extraerlo [4:15].
- El comentario
/* webpackChunkName: "modal" */ le indica a webpack el nombre legible del chunk generado [6:12].
¿Por qué se extrajo el videoID a una variable directa?
Dentro de la función que se ejecuta en la promesa, acceder al elemento link del DOM puede provocar problemas de closure en JavaScript [4:38]. La solución es almacenar el videoID en una variable antes de la promesa, de modo que el closure creado por la función asíncrona solo capture un string y no una referencia al nodo del DOM.
¿Qué hace el webpackChunkName?
Sin este comentario especial, webpack genera nombres crípticos como 2.bundle para los chunks dinámicos [5:52]. Al definir webpackChunkName: "modal", el archivo resultante se llama modal.bundle, algo mucho más legible cuando se inspecciona el build de producción [6:38].
¿Cómo se verificó que el lazy loading funciona correctamente?
Al ejecutar el build y levantar el servidor de producción, apareció un error 404 al intentar cargar modal.bundle [7:22]. El navegador buscaba el archivo en una ruta incorrecta: dist/modal.bundle en lugar de /dist/modal.bundle.
El problema estaba en la configuración de publicPath dentro de webpack, que necesitaba terminar con un slash (/) [7:55]. Sin ese carácter final, webpack construía rutas relativas erróneas para los chunks cargados dinámicamente.
Tras corregirlo y reconstruir:
- Se recargó la página y se abrió la pestaña Network del navegador.
- Al hacer clic en el botón de play, apareció una nueva petición:
modal.bundle [8:36].
- Ese archivo solo se descargó en ese momento, nunca durante la carga inicial.
Esto confirma que el lazy loading funciona: el bundle principal es más liviano y la librería del modal viaja al navegador únicamente cuando el usuario la necesita.
Esta técnica no depende de ninguna librería mágica. Requiere analizar qué partes del código son prescindibles en la carga inicial y moverlas a chunks dinámicos. Si trabajas con React, puedes lograr algo similar con React.lazy y Suspense [3:27]. Lo importante es evaluar en cada proyecto qué dependencias son candidatas a carga diferida y aplicar el patrón que mejor se adapte a tu stack.