Code splitting & lazy loading modules
Introducción
Conceptos esenciales
Uso práctico
- En ocasiones el bundle final de nuestra aplicación puede tener un peso considerable.
- El problema principal es que, para poder "ver algo" en pantalla, los usuarios tienen que descargarse toda la información y esto consume tiempo.
- Es aquí donde diferentes técnicas de llamado code splitting vienen en nuestra ayuda.
- En la documentación oficial se muestran varias de estas técnicas. La primera consiste en utilizar varios puntos de entrada para tener varios bundles. Algo que ya hemos realizando para econtrarnos con el problema de dependencias comunes (Vue) duplicadas.
- Este problema lo solucionamos con la segunda técnica, utilzar
SplitChunksPlugin
para extrapolar las dependencias comunes en diferentes trozos o "chunks" del mismo bundle. - Sin embargo la técnica más interesante es la tercera, llamada dynamic import o también lazy loading. Consiste en dividir nuestra aplicación en diferentes partes. Algunas deberá ser cargadas de inicio pero otras, seguro, solo serán necesarias bajo determinadas circunstancias. Por ejemplo, acciones del usuario.
- En nuestra configuración de Webpack vamos a comentar temporalmente la propiedad
optimization
. Ya volveremos a ella cuando hablemos de caching. - Ahora, examinando nuestra aplicación, podemos ver que el componente
CatImage
es un candidato perfecto para ser cargado de forma dinámica o diferida. Esto es posible con losimport
ECMASCRIPT. - Como usamos Vue Loader, el proceso es incluso más sencillo. Basta con que la definición del componente retorne una función que llame al método
import
.
//import CatImage from './components/CatImage.vue';
...
components: {
CatImage: () =>
import( "./components/CatImage.vue"
),
},
- Si lanzamos nuestro servidor de desarrollo veremos que chunks diferentes a
main
llamado pero sin nombre. Existen diferentes formas de aplicar un nombre a estos chunks dinámicos. - En la documentación de Webpack se aconseja utilizar la propiedad
chunkFilename
. También podemos usar los magic comments de Webpack para indicar el identificador del chunk, entre otras opciones.
CatImage: () =>
import(
/* webpackChunkName: "CatImage" */ "./components/CatImage.vue"
),
- Ahora se nos indica el nombre del chunk correctamente. Pero si examinamos el tab Network de nuestras herramientas de desarollo verás que el componente dinámico se carga de inicio. Esto se debe a que en nuestro modelo local
catImages
ya hay una imagen cargada y activa la directivav-for
, haciendo que al menos se instancie una vez. - Basta con dejar la propiedad vacía y re-lanzar para notar como el componente
catImage
sólo se carga cuando hacemos click en el botón. - Otra opción muy común al trabajar con Vue es utilizar la directiva
v-if
para cargar dinámicamente componentes. Por ejemplo un opt in para una supuesta newsletter.
<AppOptIn v-if="showOptIn" />
<a @click="showOptIn = !showOptIn" v-else href="#">Join our newsletter</a>
components: {
AppOptIn: () =>
import(
/* webpackChunkName: "AppOptIn" */ "./components/AppOptIn.vue"
)
},
- Desde las herramientas de desarrollo podemos comprobar como sólo cuando la expresión asociada a
v-if
es verdadera se lanza un request hacia el componenteAppOptIn
. - También se añade el nuevo chunk
AppOptIn
, junto amain
yCatImage
. - Por último, quiero mostrarte que Webpack añade soporte para preload/preftech. Algo que funciona genial con los imports dinámicos.
- Cuando indicamos
preftech
en un recurso, indicamos que será necesitado en un futuro cercano. Por eso, cuando el navegador se encuentra idle lo descargará. - Sin embargo, cuando indicamos
preload
en un recurso estamos diciendo que su uso es inmediato y forzando al navegador a descargarlo en paralelo. Se trata de una característica muy potente pero que, haciendo mal uso de ella, puede impactar negativamente el rendimiento de tu App. - Por todo ello vamos usar
preftech
en nuestro componenteCatImage
. Gracias a los magic comments es super sencillo (si has usado Vue Router esta sintaxis te sonará).
CatImage: () =>
import(
/* webpackChunkName: "CatImage", webpackPrefetch: true */ "./components/CatImage.vue"
),
- Ahora, si lanzamos de nuevo nuestro proceso de desarrollo verás Webpack añade a nuestro
head
la instrucción<link rel="preftecth" as "script"...
para nuestro chunkAppOptin
. - Ahora ya sabes lo sencillo que es cargar las diferentes partes de tu aplicación (páginas, componentes) utilizando Webpack y code splitting.
Código inicial
¿Tienes alguna pregunta sobre esta lección de Aprende Webpack desde cero?
Resuelve todas tus dudas sobre Webpack en la Comunidad de Escuela Vue: un lugar donde participar, aprender y ayudar. ¡Te esperamos!.
Tras el registro (si no lo has hecho ya) serás redirigido/a al canal adecuado en la Comunidad.