Improving Vue.js Router Performance

Lazy loading and code splitting in Vue.js

In the previous article, we learned about the concept of lazy loading and briefly understood how webpack bundling works under the hood. With a good understanding of basics, we can see how to apply this knowledge in a real-world Vue application. The trick you will earn today could dramatically decrease your bundle size in just a few minutes. Feel excited? Let’s see what it is!

/ router.js
import Home from './Home.vue'
import About from './About.vue'

const routes = [
  { path: '/', component: Home }
  { path: '/about', component: About }
]

As you probably noticed depending on which route we are visiting we might not need either Home.vue or About.vue (with it’s lodash dependency) yet both of them are in the same app.js bundle and will be downloaded no matter what route user visits. What a waste of downloading and parsing time!

It’s not a big deal if we are downloading one extra route but you can imagine this app growing bigger and bigger and any new addition will mean that the user will be downloading a bigger bundle on the initial visit. The more time the user has to stare at the white screen the bigger chance is that he/she will open Instagram feed with funny cat images and (maybe) never come back!

Route-based code splitting with vue-router

// router.js
import Home from './Home.vue'
import About from './About.vue'

const routes = [
  { path: '/', component: Home }
  { path: '/about', component: About }
]

We should import it dynamically. Dynamic import will generate a new bundle with this route as an entry point:

// router.js 
const routes = [
  { path: '/', component: () => import('./Home.vue') }
  { path: '/about', component: () => import('./About.vue') }
]

With above setup webpack will create three bundles:

app.js — our main bundle with app entry point (main.js) and libs/components needed in every route (in this case it’s vue and vue-router) home.js — bundle with Home page that will be downloaded only when route with / path is entered about.js — bundle with About page (and it’s dependency — lodash) that will be downloaded only when route with /about path will be entered. Side note: Bundle names here are not the real ones generated by webpack for the sake of simplicity. Webppack is actually generating something like 0.js 1.js etc depending on your configuration

This simple technique is sufficient for almost every application and can give extremely good results in a very short time. Assuming we have similar number of code in every route we reduced the initial bundle size by 50% in just 2 lines of code! The improvements are even bigger for a for an application with more routes. In fact this technique is so effective that in many cases it’s enough to solve most of the performance issues your application could have.