JAVASCRIPT

Vue 3 Lazy Loading Components with `defineAsyncComponent`

Optimize your Vue 3 application's performance and initial load time by dynamically importing components only when they are needed, using `defineAsyncComponent`.

// src/views/HomeView.vue
<template>
  <div class="home-view">
    <h1>Welcome to the Home Page</h1>
    <p>This content loads immediately.</p>
    <button @click="showModal = true">Load & Show Modal</button>

    <div v-if="showModal">
      <!-- The AsyncModal component will only be loaded when `showModal` is true -->
      <AsyncModal @close="showModal = false" />
    </div>

    <button @click="loadAnalytics = true">Load Analytics Widget</button>
    <div v-if="loadAnalytics">
      <AsyncAnalyticsWidget />
    </div>

    <h2>Other Content</h2>
    <p>More static content...</p>
  </div>
</template>

<script setup>
import { ref, defineAsyncComponent } from 'vue';

// Basic async component definition
const AsyncModal = defineAsyncComponent(() => import('../components/LazyModal.vue'));

// More advanced async component with loading, error, and delay options
const AsyncAnalyticsWidget = defineAsyncComponent({
  loader: () => import('../components/LazyAnalyticsWidget.vue'),
  loadingComponent: () => import('../components/LoadingSpinner.vue'), // Component to show while loading
  errorComponent: () => import('../components/ErrorFallback.vue'),    // Component to show if load fails
  delay: 200, // Delay in ms before showing the loading component. Default: 200ms.
  timeout: 3000 // Timeout in ms after which the error component will be displayed. Default: Infinity.
});

const showModal = ref(false);
const loadAnalytics = ref(false);
</script>

<style scoped>
.home-view {
  padding: 20px;
  font-family: sans-serif;
}
button {
  margin: 10px;
  padding: 10px 15px;
  cursor: pointer;
}
</style>


// src/components/LazyModal.vue
<template>
  <div class="modal-backdrop" @click.self="$emit('close')">
    <div class="modal-content">
      <h3>Lazy Loaded Modal</h3>
      <p>This modal content was loaded asynchronously.</p>
      <button @click="$emit('close')">Close</button>
    </div>
  </div>
</template>

<script setup>
import { defineEmits } from 'vue';
defineEmits(['close']);
console.log('LazyModal component loaded!');
</script>

<style scoped>
.modal-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}
.modal-content {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  max-width: 500px;
  text-align: center;
}
</style>

// src/components/LazyAnalyticsWidget.vue
<template>
  <div class="analytics-widget">
    <h4>Lazy Loaded Analytics Widget</h4>
    <p>Data visualization for your performance metrics.</p>
    <p>Loaded at: {{ new Date().toLocaleTimeString() }}</p>
  </div>
</template>

<script setup>
console.log('LazyAnalyticsWidget component loaded!');
</script>

<style scoped>
.analytics-widget {
  border: 1px solid #42b983;
  padding: 15px;
  margin-top: 20px;
  border-radius: 5px;
  background-color: #e6f7ed;
}
</style>

// src/components/LoadingSpinner.vue (example)
<template>
  <div class="loading-spinner">Loading...</div>
</template>
<style scoped> .loading-spinner { color: #42b983; font-weight: bold; padding: 10px; } </style>

// src/components/ErrorFallback.vue (example)
<template>
  <div class="error-fallback">Error loading component!</div>
</template>
<style scoped> .error-fallback { color: red; font-weight: bold; padding: 10px; border: 1px solid red; background-color: #ffe6e6; } </style>
How it works: This snippet demonstrates how to use Vue 3's `defineAsyncComponent` to lazy load components, improving initial page load performance. Instead of bundling all components into the main chunk, `defineAsyncComponent` creates a wrapper that only loads the target component's code when it's actually rendered. This example shows both a basic lazy load and an advanced setup with `loadingComponent`, `errorComponent`, `delay`, and `timeout` options to provide a better user experience during the loading process or in case of failure.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs