Lazy Loading Routes: Faster Initial Loads
Lazy loading routes splits your app into smaller chunks, loading code only when a user visits a specific page. This drastically cuts initial load times for large SPAs. Just be sure not to use Vue's async components directly as route components.
WHY IT EXISTS When building a single-page application (SPA) with a bundler, all your code can end up in one large JavaScript file. This bundle must be downloaded and parsed before the user sees anything, which can be very slow. Lazy loading was created to solve this by splitting the code and loading it on demand.
THE MENTAL MODEL Think of your app not as one big book, but as a library. When a user wants to read about 'User Profiles', you don't hand them the entire library at the entrance. You fetch just the 'User Profiles' section from the shelf when they ask for it. The first fetch takes a moment, but subsequent reads are instant because the app keeps it handy (cached).
HOW IT WORKS Vue Router supports lazy loading out of the box. Instead of statically importing a component at the top of your file, you provide the route's component option with a function that returns a dynamic import. A bundler like Vite or webpack sees the import() function and automatically splits that component into a separate file, or 'chunk'. Vue Router only executes this function and fetches the chunk when a user navigates to the route for the first time. On subsequent visits, it uses the cached version.
WHEN TO USE IT It's a best practice to use lazy loading for all routes in any bundled Vue application. The performance benefit is significant for medium to large apps, as it directly improves the initial page load time, a critical user experience metric. Modern bundlers make this process seamless with code splitting.
WHEN NOT TO USE IT You might group several related routes into a single chunk if they are often visited together, like a user settings area with multiple sub-pages. This avoids multiple small network requests. This is done using bundler-specific options, like webpack's /* webpackChunkName: "group-name" */ comment. The main footgun is confusing this with Vue's async components; the route component itself must be a dynamic import function, not an async component definition.
ONE CANONICAL EXAMPLE Instead of a static import that bloats the main bundle: import UserDetails from './views/UserDetails.vue'; const routes = [{ path: '/users/:id', component: UserDetails }];
You use a dynamic import function to enable lazy loading: const routes = [{ path: '/users/:id', component: () => import('./views/UserDetails.vue') }]; This simple change tells the bundler to create a separate chunk for UserDetails.vue, which Vue Router will then fetch on demand.
Read the original → router.vuejs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.