Nwose Lotanna Web Developer and Writer

Lazy loading components and code splitting in Vue.js

5 min read 1522

Lazy Loading and Code Splitting in Vue.js

Editor’s note: This Vue lazy loading tutorial was last updated on 29 April 2021.

In this Vue lazy loading tutorial, we’ll demonstrate how to lazily load the components in your Vue.js application. The aim of this demonstration is to help you understand how Vue.js handles lazy loading at the route level of abstraction with the help of webpack code splitting.

Here’s what we’ll cover:

What is Vue.js?

Vue.js is a very progressive JavaScript framework created by Evan You and the Vue core team with contributions from over 230 open source community membes. At the time of writing, Vue.js has more than 183,000 stars on GitHub. It consists of an approachable core library that focuses on the view layer only and an ecosystem of supporting libraries designed to help you tackle complexity in large single-page applications.

What is lazy loading in Vue.js?

Lazy loading is a pattern designed to delay the initialization of elements and objects until they are needed. Lazy loading means that a target DOM element, relative to a parent DOM element, is loaded and becomes visible (when there is an intersection between both elements, based on a set threshold value) only when a user scrolls through them on a webpage.

To understand lazy loading, you must first understand eager loading. Eager loading is the default approach to loading JavaScript code on to the DOM. For Vue.js, this means using the import statement to bring in a component into the app.vue file. Lazy loading refers to an approach by which all the scripts are not loaded on the DOM as the application starts. Instead, they’re only loaded when requested, which makes the JavaScript bundle size very small at initial load.

Vue.js handles loading components lazily with routes, so on the DOM you can load components only when they are needed through routes. This is done by splitting each route’s components into chunks that are separate from the main chunk loaded on initialization. This keeps the bundle size sent down to the DOM from becoming too large. Vue.js combines the async component feature and webpack’s code splitting feature to lazy-load route components.

Why is lazy loading important?

As your Vue.js project grows in size and complexity, the eager loading approach makes the JS bundle very cumbersome. This can become a problem for your end users who might be accessing your application on a mobile device or without fast-speed internet connections.

Lazy loading guarantees that your JavaScript bundle is fed to the DOM in an order of importance from the most-needed component to the least-needed ones. This approach ensures that you have control over the whole experience of the user, which includes the initial wait period when resources are loaded onto the DOM.

Vue.js lazy loading example

To demonstrate lazy loading in Vue.js, we’ll build an example Vue.js app with the Vue CLI and add routing during the configuration stage.

We made a custom demo for .
No really. Click here to check it out.

We’ll also add a third route manually to show the process for developers that are not familiar with the Vue CLI. That said, it’s always advisable to use the Vue CLI because secondary routes are already configured to be lazily loaded by default.

Starting a Vue.js project

Open up a terminal in a directory of your choice and create a new project with this command:

vue create test_project

You’ll see a follow-up questionnaire like this:

? Please pick a preset: Manually select features
? Check the features needed for your project: 
 ◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
❯◉ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

Make sure to select the router option with the spacebar just as it is selected above. Then, to save space, you can choose to store all of the configs in the package.json file. You’ll see a success message once the project is created. At this point, change the directory to the new project folder and run the application in the development environment:

cd test_project
npm run serve

Vue.js Lazy Loading Example App

It has an about component with the route navigation on the view. The two components, Home.vue and About.vue, are loaded on the DOM as soon as the application initializes. This is standard procedure and very good for small projects with minimal assets, but in large applications with a lot of components, this can be very slow to load. This is where code splitting comes in.

Open the router.js file. It should look exactly like this:

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      component: About
    }
  ]
})

This might look different for the about component section because the Vue CLI includes lazy loading for secondary routes, such as the about component in our example.

Manually adding a new route

You have two routes now: a home route that points to the home view and an about route that points to the about view. Let’s add a third view and then register a route for it.

In your views folder, create a new file and call it extra.vue. Then, copy the contents of the about.vue file into the extra.vue file. It should look like this:

<template>
<div class=”about”>
<h1>This is an extra page</h1>
</div>
</template>

To register the route, open your router.js file and add the extra code block under the routes array:

export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      component: About
    },
   {
      path: '/extra',
      name: 'extra',
      component: Extra
    }
  ]
})

The final step to get it to show in the DOM is to add it to the main App.vue file with a router-link.

Open your app.vue file and change the template section to this code block below:

<template>
<div id=”app”>
<div id=”nav”>
<router-link to=”/”>Home</router-link> |
<router-link to=”/about”>About</router-link> |
<router-link to=”/extra”>Extra</router-link>
</div>
<router-view/>
</div>
</template>

How to lazily load Vue.js components

Now that all the routes are set up in our example Vue.js app, it’s time to configure all your routes to be lazily loaded on request.

Open your router.js file and copy/paste the code block below into it:

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
function lazyLoad(view){
  return() => import(`@/views/${view}.vue`)
}
export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: lazyLoad('Home')
    },
    {
      path: '/about',
      name: 'about',
      component: lazyLoad('About')
    },
    {
      path: '/extra',
      name: 'extra',
      component: lazyLoad('extra')
    }
  ]
})

Here’s a breakdown of what was done to make these views load lazily:

Removing import statements

Initially, you may have noticed there were import statements for Vue.js, Router, Home, About, and extra. These statements are the main thing driving the eager loading of components, so when you change to the lazy loading approach, you have to remove those import statements.

lazyLoad function

The Vue lazyLoad function was created to make the import statement clean. Without this function, every component would have a long import statement. With it, you can simply call the function and pass in the route as args.

webpack import statement

The import statement that tells webpack to lazily load components must be embedded into the routes section instead of the import section at the start of the script.

To test the loading strategy, run the application again in development:

npm run serve

Open it up at http://localhost:8080/ in your browser and open developer tools. Click on the network section and choose the JS tab.

As you can see, the JavaScript chunks loaded on the DOM are split chronologically into numbers, where the first one (0.js) is the home view, the second (1.js) is the about view, which only gets added to the DOM on click, and the third (2.js) is the extra view, which also gets added to the DOM on request.

At this stage, you can also verify that the lazy loading worked by building out the application for production with the command:

npm run build

These three chunks will be duly represented as separate independent and lazily loaded chunks by webpack.

Conclusion

This introductory tutorial is designed to show you how Vue.js handles lazy loading at the route level of abstraction with the help of webpack code splitting. The importance of lazy loading components might not be as apparent in small Vue.js projects, but as your project grows complex, it becomes advisable to implement lazy loading in your workflow for efficiency and optimal use of resources.

Experience your Vue apps exactly how a user does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket. https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps - .

Nwose Lotanna Web Developer and Writer

Leave a Reply