Light & Lazy Asynchronous patterns for Vue Apps

Toronto 16th Nov 2018

GitHub icon
Twitter icon


San Martin Morote

Vue core team

Remote Freelance Developer


GitHub icon

Prototyping is fun

ReBuild plugins in Vue

Code Splitting

You should split your code

It all starts with webpack

Dynamic Import

import('a_package').then(module => module.default)
import('./utils.js').then(module => module.log)
const aPackage = () => import('a_package')
const utils = () => import('./utils.js')

Configure Webpack




import(/* webpackPrefetch: true */ 'LoginModal')
<link rel="prefetch" href="login-modal-chunk.js" />


import(/* webpackPreload: true */ 'ChartingLibrary')
<link rel="preload" href="chunk.js" />

Lazy-Loading components


import Calendar from '@/components/Calendar.vue'
const Calendar = () => import('@/components/Calendar.vue')


// router.js
const Home = () => import('@/views/Home')
const User = () => import('@/views/User')

const routes = [
  { path: '/', component: Home },
  { path: '/users/:id', component: User },


// App.vue
const Search = () => import('@/components/Search')

export default {
  components: { Search }



The real deal

โœ‚๏ธ vendors

Lazy load Recipee ๐Ÿฅ˜

  • Local imports
  • Lazy load view components


Dynamic Components


<component :is="dynamicComponent"/>
// inside of a component method

// local or global component
this.dynamicComponent = 'UserCard'

// component descriptor
// import UserCard from './UserCard'
this.dynamicComponent = UserCard

In-Render functions

export default {
  render (h) {
    return h(this.dynamicComponent)
  methods: {
    changeDisplayedComponent () {
      this.dynamicComponent = 'UserCard'
      // or
      this.dynamicComponent = UserCard


import Calendar from '@/components/Calendar.vue'
const Calendar = () => import('@/components/Calendar.vue')

Dynamic Lazy components

<component :is="dynamicComponent"/>
// inside of a component method
this.dynamicComponent = () => import('./UserCard')
render(h) { return h(this.dynamicComponnet) }

Dynamic Imports with Expressions


let webpack creates chunks ๐Ÿ‘Œ


import(myComponentPath) // ๐Ÿ˜ฑ โ˜ ๏ธ

your app

Hint Webpack the best you can

import(myComponentPath) // ๐Ÿ˜ฑ โ˜ ๏ธ
import(`@/components/Lazy${name}.vue`) // ๐Ÿ™Œ
import(`@/components/async/${name}.vue`) // ๐Ÿ’ฏ

Lazy loading Dynamic Components


<ExamplePreview name="counter"/>

dynamic components + computed = ๐Ÿ‘Œ

computed: {
  demoComponent() {
    // make demoComponent depend on name
    const name =
    return () =>
<component :is="demoComponent"/>

Analyzing your app


when your app is unmaintainable but you still care

vue ui

Lazy Load

  • Local imports
  • Always lazy load views
  • Lazy load big local components

Dynamic import expressions

  • As precise as possible
  • Prefetch flag (can wait)
  • Preload (needed now)

Handling Errors

โŒ Error

// in a component method
this.error = null
return import('./Component.vue').catch(err => {
  this.error = err
<p class="danger" v-if="error">{{ error }}</p>

โณ LOading

this.error = null
this.pending = true
return import('./Component.vue').then(module => {
  this.pending = false
  return module
}).catch(err => this.error = err)
<p class="danger" v-if="error">{{ error }}</p>
<p class="info" v-else-if="pending">Loading...</p>

when you realize you have been writing the same thing over and over

Async component factory

const AsyncComponent = () => ({
  component: import('./MyComponent.vue'),
  loading: LoadingComponent,
  error: ErrorComponent,
  delay: 200,
  timeout: 3000

๐Ÿ’ Vue-promised

<Promised :promise="componentPromise">
  <p slot="pending">Loading component</p>
  <p slot="rejected" slot-scope="error">
    {{ error.message}}

๐Ÿ‘‰ Github repo

Thanks! ๐Ÿ––

GitHub icon

Light, lazy asynchronous patterns for Vue Apps

By Eduardo San Martin Morote

Light, lazy asynchronous patterns for Vue Apps

We keep shipping more and more features in our Web applications, and as a result, we ship heavier apps that take more time to load. So we use bundlers like webpack to split our application code into multiple bundles and load them asynchronously. As a result, we end up having asynchronous code pretty much everywhere in our apps. This means that we need to handle unexpected errors that were otherwise impossible, like network ones, handle loading state and make sure the application is able to recover from these errors. During this talk, we will take a look at different patterns about handling asynchronous request correctly in Vue applications in order to make our Apps feel light, fast and reliable everywhere.

  • 1,580
Loading comments...

More from Eduardo San Martin Morote