Javascript is required
Mokkapps Logo

Vue Tip: Delay Loading Appearance of Spinner

Michael Hoffmann (Mokkapps) - Senior Frontend Developer (Freelancer)
Jul 12, 2022
1 min read
Delay Loading Appearance of Spinner Image

Eager delay spinners are not a good user experience as they can make a snappy user interface feel slower. We can provide a better user experience (UX) by delaying spinners to appear only after a perceivable delay.

To achieve this improved UX, you can use AsyncComponent.

Vue provides the defineAsyncComponent function to lazy load components:

<template>  <AsyncComp /></template><script setup>import { defineAsyncComponent } from 'vue'const AsyncComp = defineAsyncComponent(() => {  return new Promise((resolve, reject) => {    // ...load component from server    resolve(/* loaded component */)  })})</script>

defineAsyncComponent accepts a loader function that returns a Promise. The resolve callback should be called if the component has been loaded, and the reject callback to indicate that loading the component has failed.

Now let's implement the delayed loading spinner by using the advanced options of the defineAsyncComponent function:

<template>  <AsyncComp /></template><script>import { defineAsyncComponent } from 'vue'import Loading from './components/Loading'export default {  components: {    AsyncComp: defineAsyncComponent({      // the loader function      loader: () =>        new Promise((resolve) => {          setTimeout(() => {            resolve(import('./components/HelloWorld.vue'))          }, 2000)        }),      // A component to use while the async component is loading      loadingComponent: Loading,      // Delay before showing the loading component. Default: 200ms.      delay: 500,    }),  },  data() {},}</script>

This demo simulates a network request to fetch HelloWorld.vue from a server which takes 2 seconds:

 new Promise((resolve) => {  setTimeout(() => {    resolve(import('./components/HelloWorld.vue'))  }, 2000)})

The loading component Loading.vue is shown after a delay of 500ms, defined with delay: 500.

You can try it yourself in this StackBlitz playground:

If you liked this Vue tip, follow me on Twitter to get notified about new tips, blog posts, and more content from me. Alternatively (or additionally), you can also subscribe to my newsletter.