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 buildoutput, 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.onErrorand Vite'svite:preloadErrorevent.
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.