Dynamic Imports in Vue.js for better performance

Paul Melero

Paul Melero

Apr 15, 2019
3 min read
Share on Twitter or LinkedIn

I bet you are already familiar with the terms "code splitting" and "lazy loading". Let's take the latter definition from Webpack's docs:

Lazy, or "on demand", loading is a great way to optimize your site or application. This practice essentially involves splitting your code at logical breakpoints, and then loading it once the user has done something that requires, or will require, a new block of code. This speeds up the initial load of the application and lightens its overall weight as some blocks may never even be loaded.

This kind of feature should be done by default by the frameworks we use, as some people have suggested. (Also in the React ecosystem)

# The meat:

Whenever it's possible, I'd recommend to use dynamic imports to import components. They will be lazily loaded (by Webpack) when needed.

// Instead of a usual import
import MyComponent from "~/components/MyComponent.js";

// do this
const MyComponent = () => import("~/components/MyComponent.js");

# The explanation:

When using Webpack to bundle your application, you may use different ways to work with modules (ES Modules, CJS, AMD...). If you choose the ESM way (which is the recommended), you will have this kind of syntax:

import MyComponent from "~/components/MyComponent.js";

Notice that there are several use cases where we would like to use asyncronous components. As explained by Alex Jover in this article:

  • In component importing
  • In Vue Router, for components mapping
  • In Vuex modules

Let's take a look at the syntax and focus on the import part.

If you are using Webpack (or Parcel!), that syntax is going to be transformed on compilation time and these tools are going to usePromises to load asynchronously your assets/modules/components.

Why the need of an arrow function, you might be wondering: As Alex explained, we need to wrap the import with an arrow function to be resolved (remember, promises...) only when executed.

To demonstrate that they are fully lazy loaded I've prepared a repository (using Nuxt.js). It has 2 pages, each of them use different techniques (With and Without dynamic imports) to import 2 components (component "A" and component "B").

We will see how, when loading the page with dynamic imports, webpack loads 2 separate files after the navigation. But, the page component itself (/without) using regular imports, is heavier because it loads everything at once.

Image showing network waterfall when navigating to both pages. And the differences between both techniques (with and without dynamic imports)

Yes, by using this technique, Webpack will create separate files ("chunks") to load them when needed (lazily). Custom chunk naming can be done with Magic comments but that will be the subject of another article 😉.

Image showing the result of nuxt build. See how different chunks are created for components A and B when dynamic imports are used!

# That's it!

For a deeper exploration of code splitting techniques check:

PS: For this example repo I have used webpack@4.29.6 and Nuxt@2.4.0 which uses Vue@2.5.22.

Don't miss out anything about Vue, your favourite framework.

Subscribe to receive all the articles we publish in a concise format, perfect for busy devs.

Related Articles

Achieve Max Performance loading your images with v-lazy-image

Don't you know what to do to improve your web performance? Learn Progressive Image Loading, a technique used by Spotify, Medium and Netflix.

Alex Jover Morales

Alex Jover Morales

Aug 30, 2021

Use Responsive Images with v-lazy-image

Is Web Performance a priority for you? Then read this article! You'll learn how to lazy load images with srcset and picture tag using v-lazy-image.

Alex Jover Morales

Alex Jover Morales

Aug 23, 2021

Use Web Workers in your Vue.js Components for Max Performance

Learn how to get up to 20x performance improvement of Vue.js components that rely on heavy tasks so they render and load faster

Alex Jover Morales

Alex Jover Morales

Mar 31, 2020


VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.

Learning Partner