DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Brian Neville-O'Neill
Brian Neville-O'Neill

Posted on • Originally published at blog.logrocket.com on

Lazy loading in Vue JS

Vue

Vue JS is a very progressive JavaScript framework created by Evan You and the Vue core team and with contributions from over 230 open source community lovers. Vue is used by more than 870,000 people and has been starred 140,000 times on GitHub. It consists of an approachable core library that focuses on the view layer only, and an ecosystem of supporting libraries that helps you tackle complexity in large single-page applications.

In this post, you will be introduced to ways to lazily load your components in Vue JS.

Before you start

This post is suited for all stages of developers that use Vue JS, and this includes beginners. Here are a few prerequisites you should already have before going through this article.

You will need the following:

  • Node.js version 10.x and above installed. You can verify if you do by running the command below in your terminal/command prompt:
node -v
Enter fullscreen mode Exit fullscreen mode
  • The Node Package Manager 6.7 or above (NPM) also installed
  • A code editor: Visual Studio Code is highly recommended
  • Vue’s latest version, installed globally on your machine
  • Vue CLI 3.0 installed on your machine. To do this, uninstall the old CLI version first:
npm uninstall -g vue-cli
Enter fullscreen mode Exit fullscreen mode
  • Then, install the new one:
npm install -g @vue/cli
Enter fullscreen mode Exit fullscreen mode

What is lazy loading?

To understand lazy loading, you have to first know what eager loading means. Eager loading is the default approach of 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. On the other hand, lazy loading refers to an approach where all of the scripts are not loaded on the DOM as the application starts, instead, they are only loaded when requested, making the JavaScript bundle size very small at initial load.

LogRocket Free Trial Banner

Why is lazy loading important?

As your Vue project grows in size and complexity, the eagerly loading approach makes the JS bundle very cumbersome and that can become a big 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 less needed ones. This approach ensures that you, the developer have control over the whole experience of the user which includes the initial wait period when resources are loaded on to the DOM.

How Vue JS handles lazy loading

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 separate from the main chunk loaded on initialization so that the bundle size sent down to the DOM does not become too large. Vue JS combines the async component feature and webpack’s code splitting feature to lazy-load route components.

Demo: What you will be building

You will build a Vue JS application with the new Vue CLI 3 and add routing during the configuration stage and also add a third route manually to ensure for developers that are not familiar with the CLI.

It is always advisable to use the Vue CLI as a Vue JS developer because secondary routes are already configured to be lazily loaded by default, however, you will be shown how to do this manually in this post.

Starting a Vue project

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

vue create test_project
Enter fullscreen mode Exit fullscreen mode

You will 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
Enter fullscreen mode Exit fullscreen mode

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 will 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
Enter fullscreen mode Exit fullscreen mode

vue js 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
    }
  ]
})
Enter fullscreen mode Exit fullscreen mode

This might look different for the about component section as the new CLI 3 includes lazy loading for secondary routes like the about component in our case.

Manually adding a new route

You have two routes now, a home route that points to the home view and the about route that points to the about view. Let us add a third view and then register a route for it. In your views folder, create a new file and call it extra.vue and then copy the content 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>
Enter fullscreen mode Exit fullscreen mode

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
    }
  ]
})
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Lazily loading our components

Now that all your routes are set up, you will now configure all your routes to be lazily loaded on request. Open your router.js file and copy 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')
    }
  ]
})
Enter fullscreen mode Exit fullscreen mode

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

  • Removal of import statements: Initially you noticed there were import statements for Vue, Router, Home, About and extra. These statements are the main drivers of eager loading of components so when you change approach, you have to remove those import statements.
  • A lazyLoad function: This function was created to handle to make the import statement clean, without this function every component will have a long import statement. With it, however, you just 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
Enter fullscreen mode Exit fullscreen mode

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

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

At this stage, you can also confirm this by building out the application for production with the command:

npm run build
Enter fullscreen mode Exit fullscreen mode

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

Conclusion

This is an introduction to 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 easily felt in small Vue projects but as your project gets complex it becomes very obvious and therefore advisable to implement lazy loading in your workflow for efficiency and optimal use of resources. Happy hacking!


Plug: LogRocket, a DVR for web apps

Β 
LogRocket Dashboard Free Trial Banner
Β 
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
Β 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
Β 
Try it for free.


The post Lazy loading in Vue JS appeared first on LogRocket Blog.

Top comments (1)

Collapse
 
tboss profile image
Travis

Question. I have a SPA that is maybe 7 components, could I simply lazy load the app.vue to have it lazy load components of the page below the fold? Reason being is one of the vues has a lot of images that I would prefer to load if the user scrolls to, which actually might now happen since the form that is required is above the fold.

Thanks.

πŸ› See a bug on this page?

Join our team and help us fix it. We're hiring for a Senior Full Stack Engineer β€” Head here to learn more and apply.