Lazy Loading Components
Learn about lazy loading components and how to manage these in our application using the defineAsyncComponent function.
We'll cover the following...
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:
const AsyncComponent = () => ({// The component to load (should be a Promise)component: import('./MyComponent.vue'),// A component to use while the async component is loadingloading: LoadingComponent,// A component to use if the load failserror: 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
.
import { defineAsyncComponent } from 'vue'const AsyncComp = defineAsyncComponent({// The factory functionloader: () => import('./Foo.vue')// A component to use while the async component is loadingloadingComponent: LoadingComponent,// A component to use if the load failserrorComponent: 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 attemptsretry()} 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>
The PanelModal
component is a div that slides from the right side of the ...