Aprende Webpack desde cero

Code splitting & lazy loading modules

  • 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 los import 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 directiva v-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 componente AppOptIn.
  • También se añade el nuevo chunk AppOptIn, junto a main y CatImage.
  • 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 componente CatImage. 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 chunk AppOptin.
  • Ahora ya sabes lo sencillo que es cargar las diferentes partes de tu aplicación (páginas, componentes) utilizando Webpack y code splitting.

No te pierdas ninguna novedad

Escuela Vue en Twitter

Participa en la Comunidad Escuela Vue

Comunidad Escuela Vue