DEV Community

Cover image for Lazy loading in Vue using Webpack's code splitting
Alex Jover
Alex Jover

Posted on • Originally published at alexjoverm.github.io

Lazy loading in Vue using Webpack's code splitting

When a Vue app gets large, lazy loading components, routes or Vuex modules using Webpack's code splitting will boost it by loading pieces of code only when needed.

We could apply lazy loading and code splitting in 3 different levels in a Vue app:

But there is something they all have in common: they use dynamic import, which is understood by Webpack since version 2.

Lazy load in Vue components

This is well explained in the "Load components when needed with Vue async components" on Egghead.

It's as simple as using the import function when registering a component:

Vue.component('AsyncCmp', () => import('./AsyncCmp'))
Enter fullscreen mode Exit fullscreen mode

And using local registration:

new Vue({
  // ...
  components: {
    'AsyncCmp': () => import('./AsyncCmp')
  }
})
Enter fullscreen mode Exit fullscreen mode

By wrapping the import function into an arrow function, Vue will execute it only when it gets requested, loading the module in that moment.

If the component importing is using a named export, you can use object destructuring on the returned Promise. For example, for the UiAlert component from KeenUI:

...
components: {
  UiAlert: () => import('keen-ui').then(({ UiAlert }) => UiAlert)
}
...
Enter fullscreen mode Exit fullscreen mode

Lazy load in Vue router

Vue router has built in support for lazy loading. It's as simple as importing your components with the import function. Say we wanna lazy load a Login component in the /login route:

// Instead of: import Login from './login'
const Login = () => import('./login')

new VueRouter({
  routes: [
    { path: '/login', component: Login }
  ]
})
Enter fullscreen mode Exit fullscreen mode

Lazy load a Vuex module

Vuex has a registerModule method that allow us to dynamically create Vuex modules. If we take into account that import function returns a promise with the ES Module as the payload, we could use it to lazy load a module:

const store = new Vuex.Store()

...

// Assume there is a "login" module we wanna load
import('./store/login').then(loginModule => {
  store.registerModule('login', loginModule)
})
Enter fullscreen mode Exit fullscreen mode

Conclusion

Lazy loading is made extremely simple with Vue and Webpack. Using what you've just read you can start splitting up your app in chunks from different sides and load them when needed, lightening the initial load of the app.

If you like it, please go and share it! You can follow me on this blog or on twitter as @alexjoverm. Any questions? Shoot!


Originally published at alexjoverm.github.io on July 7, 2017.

Top comments (4)

Collapse
 
onekiloparsec profile image
Cédric Foellmi

So simple. I love Vue for that. One question remains open to me: when do you consider your app to be large enough to split it?

Collapse
 
alexjoverm profile image
Alex Jover

I'd say there is no right answer for this. The best you can do is, when you consider it has grown and you wanna start splitting and chunking, benchmark the before and after of the splitting (first time load, initial load, navigating time...)

Said that, depends on which splitting:

  • For components, when they make sense to be lazy loaded (ej: Modals, Tooltip...)
  • Routes and Store: when you identify independent modules (ej: Products, Users management, ...) that they have not many dependencies aside from login token and so on
Collapse
 
onekiloparsec profile image
Cédric Foellmi

That's great tips, thanks a lot. Among the bazillions of things one needs to think about when building large stuff alone, this kind of comments help starts taking first decisions.

Collapse
 
tribex profile image
Joshua Bemenderfer

I generally split based on which paths I expect the user to take through the app. If there are multiple types of users, then components specific to each type of user or more common for one are split away from the main app.