Skip to the solution
MediumFrontend12 min read

How do you lazy-load routes and components in Vue?

822 views

The problem

Question presented to candidate: "Our Vue app's main bundle has grown past what we want on a phone, and most users never open the admin area. How would you lazy-load routes and heavy components, how would you check it worked, and what can go wrong in production?"

What a strong answer should cover:

  • Route-level splitting: give the route a function, component: () => import("./views/AboutView.vue"); the bundler emits a separate chunk and the router fetches it the first time the route is visited, then reuses it.
  • Component-level splitting: defineAsyncComponent(() => import("./HeavyChart.vue")) for heavy parts of a page that are not always shown.
  • Do not wrap route components in defineAsyncComponent; the router handles lazy routes itself (and vue-router 5 warns).
  • Verify with the build: separate files in vite build output, and only the needed chunk requested on navigation in the browser's network panel.
  • Grouping: related routes can share one chunk via bundler config (in Vite 8, Rolldown's output.codeSplitting.groups), but careless groups can pull shared code into the group and get it preloaded on every page.
  • Failure handling: a chunk can fail to load (offline, or an old tab after a deploy); handle it with router.onError and Vite's vite:preloadError event.

Clarifying questions expected:

  • "Which routes are on the critical path for most users, and which are rarely visited?"
  • "How do deploys work: are old asset files kept for a while after a release?"

Code / implementation expected: Yes β€” a router table with lazy routes, a defineAsyncComponent for one heavy component, and the build output to prove the split.

  • vue
  • lazy-loading
  • code-splitting
  • vue-router

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

12 min read Β· 11 sections

Read the code

Router table with lazy routes and nested lazy children (vue-router 5)
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "./views/HomeView.vue"; // eager: part of the entry chunk

export const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: "/", component: HomeView },
    // Lazy: a function returning a dynamic import(). Vite emits a separate chunk.
    { path: "/about", component: () => import("./views/AboutView.vue") },
    {
      path: "/admin",
      component: () => import("./views/admin/AdminLayout.vue"),
      children: [
        { path: "users", component: () => import("./views/admin/AdminUsers.vue") },
        { path: "settings", component: () => import("./views/admin/AdminSettings.vue") },
      ],
    },
  ],
});
Vite 8 config grouping admin routes into one chunk without capturing shared code
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

export default defineConfig({
  plugins: [vue()],
  build: {
    rolldownOptions: {
      output: {
        // Vite 8 bundles with Rolldown: codeSplitting replaces manualChunks.
        codeSplitting: {
          groups: [
            { name: "admin", test: /src\/views\/admin\//, priority: 1 }, // every admin screen in one chunk
            // vue, vue-router and the plugin-vue export helper (shared by every SFC) go in vendor,
            // with a higher priority so the admin group cannot capture them.
            { name: "vendor", test: /node_modules|plugin-vue:export-helper/, priority: 2 },
          ],
        },
      },
    },
  },
});

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 36 of 92 in Vue.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Vue.js questions
Up nextMedium

What are Vue Router navigation guards?

Continue