lukes.tips

How to manually load async components in Vue 3 and Vite

Introduction to code splitting and lazy loading

In single-page applications (SPAs), as your app grows in size so does your bundle size, resulting in potentially longer wait time for your users. This is due to the need for downloading larger entry points to access your app.

One effective solution to optimize the entry point size is by applying code splitting & lazy loading. This practice involves loading components as they are needed rather than preemptively loading all up front.

Vue 3 provides a very easy way to achieve code splitting and lazy loading for our components using async components.

Trade-offs when using async components

While async components offer the advantage of performance optimization, there is also a downside. Due to components only being fetched when they are rendered, users may experience a delay between their interaction with your app and the actual rendering of the async component. The user experience of interacting with a page and then needing to wait is far from ideal.

While Vue 3’s defineAsyncComponent provides advanced options such as loading and error states, there will be scenarios where we want our async component to render directly, without showing a loader.

Prefetching and preloading

To strike a balance between keeping our entry points small, while ensuring a smooth user experience, we can consider prefetching or preloading our async components. This involves fetching these resources in the background, slightly ahead of when they will be rendered.

Modern browsers natively support both prefetch and preload. However, when we are using tools like Webpack or Vite, we need to ensure they are compatible with these features too.

Webpack does offer the option to automatically prefetch and preload components, thereby harnessing the benefits of browser prefetching & preloading. For more information on this feature, head over here.

Prefetching and Preloading in Vite

As of version 5.2.4, Vite does not directly offer a feature to prefetch and preload similar to Webpack. However, a workaround is available to manually load our async components as needed. You just need to call the setup() method on the object returned from the defineAsyncComponent function.

// Import your component as normal
const AsyncComponent = defineAsyncComponent(() => import('path/to/component.vue'))

// Whenever we want to prefetch the component we just need to call the `setup()` method, this will begin the fetch of the component in the browser!
AsyncComponent.setup()

Remember, this method serves as a workaround and does not take advantage of browser prefetching. Still, it mitigates the user experience issues provided the setup() method is called and the component is given ample load time before it’s rendered.