...

/

Lazy Loading Components

Lazy Loading Components

Learn about lazy loading components and how to manage these in our application using the defineAsyncComponent function.

Not every component is equal. Some are more important and should be displayed immediately, while content further down the page won’t be visible right away anyway, so it can be loaded a bit later. Similarly, content that’s shown in modals and popups, especially if there’s a lot of it, doesn’t need to be loaded upfront.

Async components

There’s a slight difference between how async components are defined in Vue 2 and Vue 3. In Vue 2, async components can be used by providing a function that returns an object like this:

Press + to interact
const AsyncComponent = () => ({
// The component to load (should be a Promise)
component: import('./MyComponent.vue'),
// A component to use while the async component is loading
loading: LoadingComponent,
// A component to use if the load fails
error: ErrorComponent,
// Delay before showing the loading component. Default: 200ms.
delay: 200,
// The error component will be displayed if a timeout is
// provided and exceeded. Default: Infinity.
timeout: 3000
})

The defineAsyncComponent function

However, in Vue 3, we need to use the defineAsyncComponent function. Besides changing the names of some properties, a few other properties were added, namely suspensible and onError.

Press + to interact
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent({
// The factory function
loader: () => import('./Foo.vue')
// A component to use while the async component is loading
loadingComponent: LoadingComponent,
// A component to use if the load fails
errorComponent: ErrorComponent,
// Delay before showing the loading component. Default: 200ms.
delay: 200,
// The error component will be displayed if a timeout is
// provided and exceeded. Default: Infinity.
timeout: 3000,
// Defining if component is suspensible. Default: true.
suspensible: false,
/** *
* @param {*} error Error message object
* @param {*} retry A function that indicating whether the async component
* should retry when the loader promise rejects
* @param {*} fail End of failure
* @param {*} attempts Maximum allowed retries number
*/
onError(error, retry, fail, attempts) {
if(error.message.match(/fetch/) && attempts <= 3) {
// retry on fetch errors, 3 max attempts
retry()
} else {
// Note that retry/fail are like resolve/reject of a promise:
// one of them must be called for the error handling to continue.
fail()
}
},
})

Let’s look at how we can implement a lazy-loaded component. We need the PanelModal, PanelModalContent, LoadingComponent, ErrorComponent, and PanelModalExample components for this example.

Let’s start with the PanelModal component:

<template>
<div :class="[$style.lazyModal, open && $style.open]">
<slot />
</div>
</template>
Template for the PanelModal component

The PanelModal component is a div that slides from the right side of the ...