Hard20 minVue.js Fundamentals
UpdatedAug 5, 2026
Edit

Async components and Suspense

CONCEPTS:Vue Async Components

Question Variations

  • "What is the difference between an async component and an async setup function?"
  • "How does Suspense decide when to hide its fallback?"
  • "How would you retry a failed dynamic import?"

Why This Is Asked

This evaluates practical code-splitting and asynchronous rendering knowledge. Interviewers want candidates to distinguish lazy loading a component’s code from waiting for asynchronous setup, and to explain where loading and error states belong in a resilient UI.

Key Concepts

  • defineAsyncComponent: Defers loading a component implementation.
  • Suspense: Coordinates nested async dependencies and fallback content.
  • Error boundaries: Async component loaders can provide an error component and retry logic.
  • UX: Loading boundaries should be placed around meaningful, independently useful parts of a page.

Question Variations

  • “What is the difference between an async component and an async setup function?”
  • “How does Suspense decide when to hide its fallback?”
  • “How would you retry a failed dynamic import?”

Answers by Technology

+ Add Variant
Vue.jsImprove this answer ✏️

Expected Answer (Vue.js 3.5.40)

An async component defers loading a component definition, usually through a dynamic import passed to defineAsyncComponent. This creates a code-splitting boundary: the component’s JavaScript is fetched only when Vue needs to render it. The async loader can define its own loading, delay, timeout, error, and retry behavior.

Suspense is a rendering coordination boundary. It can show fallback content while its default slot contains unresolved asynchronous dependencies, including an async component configured to suspend or a component with asynchronous setup. Once all dependencies for the boundary resolve, Vue displays the default content. These are related but separate: an async component controls how code is loaded, while Suspense coordinates what the user sees while async dependencies are pending.

In Vue 3.5.40, place a suspense boundary around a meaningful UI unit so the fallback does not unnecessarily hide already useful page content. Handle failure deliberately: a dynamic import can fail due to network or deployment issues, and an error component or retry policy should give users a recovery path.

Why It Matters

Lazy loading can reduce initial JavaScript and improve startup performance, but poorly placed loading boundaries create blank pages or confusing layout shifts. Robust error handling is essential because dynamic chunks are independent network requests.

Example Code

import { Suspense, defineAsyncComponent, defineComponent, h } from 'vue';

const AsyncProfile = defineAsyncComponent({
  loader: () => import('./ProfilePanel.vue'),
  delay: 200,
  timeout: 10_000,
});

export const ProfileSection = defineComponent({
  setup() {
    return () => h(Suspense, null, {
      default: () => h(AsyncProfile),
      fallback: () => h('p', 'Loading profile…'),
    });
  },
});

Common Mistakes

  • Treating an async component as an automatic loading UI: The loader fetches code; the application still needs an intentional fallback or loading component.
  • Putting one Suspense boundary around the entire application: A single slow feature can hide unrelated content that could have rendered immediately.
  • Ignoring chunk-load failures: A deployment mismatch or offline user can make import() fail, so provide an error path or retry strategy.

Follow-up Questions

  • What does Suspense wait for? (Answer: Asynchronous dependencies in its default slot, such as async setup and suspensible async components.)
  • How can an async component report failure? (Answer: Configure errorComponent or use onError to retry or fail after a chosen number of attempts.)

References