Vue 3 is fast by default, but large applications can still benefit from deliberate optimisation strategies. This article covers the most impactful techniques.
// Instead of static imports, use dynamic imports
const routes = [
{ path: '/', component: () => import('./views/HomeView.vue') },
{ path: '/dashboard', component: () => import('./views/DashboardView.vue') },
{ path: '/settings', component: () => import('./views/SettingsView.vue') },
]
// Each route is now a separate chunk loaded on demand
import { defineAsyncComponent } from 'vue'
const HeavyChart = defineAsyncComponent({
loader: () => import('./components/HeavyChart.vue'),
loadingComponent: LoadingSpinner,
errorComponent: ErrorMessage,
delay: 200,
timeout: 5000,
})
<Suspense>
<HeavyChart :data="chartData" />
<template #fallback><LoadingSpinner /></template>
</Suspense>
<!-- Only re-renders when id or selected changes -->
<div v-for="item in list" :key="item.id" v-memo="[item.id, item.selected]">
<ExpensiveItem :item="item" />
</div>
import { shallowRef } from 'vue'
// Only tracks the top-level reference, not deep properties
// Useful for large datasets or third-party objects
const bigDataset = shallowRef(largeArray)
// Trigger reactivity by replacing the whole value
bigDataset.value = [...bigDataset.value, newItem]
<!-- Cache expensive components between route switches -->
<RouterView v-slot="{ Component }">
<KeepAlive :include="['DashboardView', 'ProfileView']">
<component :is="Component" />
</KeepAlive>
</RouterView>
All Comments