Vue Performance Skill
Baseline 2026-07: Vue 3.5/3.6, Vite 8 (Rolldown). Rule zero: measure before optimizing — read diagnose first, then jump to the matching fix reference.
Triage Table
| Symptom | Likely area | Reference |
|---|---|---|
| Slow first load, big JS download | Bundle | bundle |
| Slow interaction / janky typing / laggy lists | Rendering | rendering |
| Tab slows down over time, crashes after long use | Memory leaks | memory-leaks |
| "It feels slow" (unquantified) | Measure first | diagnose |
Quick wins checklist (apply before deep work)
shallowReffor large objects/arrays that are replaced, not mutated (API responses).v-forwith stable:keys; computed for filtered lists (never method calls in template).- Virtualize lists > ~200 rows (
useVirtualList/vue-virtual-scroller). - Route-level code splitting (
() => import(...)) — free with file-based routing. - Heavy below-the-fold widgets →
defineAsyncComponent(+ Nuxt: lazy hydration). - Props stability: don't create fresh objects/arrays/closures inline in hot templates.
- Watchers: never
deep: trueon large trees when a getter on the specific field works. - Vue 3.6+: flip profiler-identified hot components to Vapor Mode (see
vueskill → vue-36-vapor).
Anti-rules (do NOT)
- Do not sprinkle
v-memoeverywhere — it's for the rare proven-hotv-forcase and adds its own comparison cost. - Do not switch working code to
markRaw/shallowReactivespeculatively; each removes reactivity guarantees someone else relies on. - Do not "optimize" without a before/after number from the profiler or bundle report.