Mejora el rendimiento de Vue.js: guía definitiva 2026
Si tu aplicación Vue.js es lenta, es casi siempre porque el bundle es demasiado grande, la reactividad detecta cambios innecesarios o estás renderizando componentes que nadie ve. La optimización rendimiento Vue.js se reduce a tres movidas: code splitting (dividir el bundle), reactividad selectiva (reactividad solo donde importa) y rendering eficiente (v-if, keys, v-memo). Implementadas correctamente, mejoran LCP entre 40-60% y el tiempo de interacción cae dramáticamente.
En 30 segundos
- Code splitting por rutas reduce el bundle inicial hasta 60%, bajando LCP (Largest Contentful Paint) a niveles competitivos.
- shallowRef y estructura de estado normalizado evitan re-renders innecesarios, mejorando Update Performance entre 40-65%.
- v-if vs v-show: usá v-show para toggles frecuentes (60+ veces/segundo), v-if para cambios raros (usuarios navegando).
- Virtual scrolling convierte listas de 10,000+ elementos en 50 elementos renderizados reales (el resto es DOM virtual).
- Lazy loading de rutas + preload inteligente suma 30-50% en velocidad de navegación según VueSchool.
Vue.js es un framework JavaScript creado por Evan You en 2014 que permite construir interfaces reactivas con un rendimiento que depende casi completamente de cómo implementés el código. A diferencia de React o Angular, Vue es menos forgiving: si generás un bundle de 500KB o tu estado es un objeto anidado infinito que se vuelve reactivo todo junto, te lo va a cobrar con creces. La buena noticia es que Vue está diseñado para ser optimizable si sabés qué hacer.
Por qué importa el rendimiento en Vue.js
Ponele que lanzás un dashboard para monitoreo de infraestructura. Funciona bárbaro en local, probás en producción con datos reales (100,000 registros, actualización cada segundo), y de repente el browser se congela cada dos por tres. El usuario no puede scrollear, los clicks se demoran 3 segundos, todo se siente pegajoso.
Eso es un problema de rendimiento en Vue. Y no es raro. El framework está optimizado para la mayoría de casos de uso (sitios corporativos, landing pages, dashboards pequeños), pero cuando empezás a meter datos masivos o complejidad real, necesitás saber exactamente qué está pasando bajo el capó.
Core Web Vitals (LCP, INP, CLS) son métricas que Google usa para ranking. Una aplicación lenta pierde posiciones SEO automáticamente. Además, por cada segundo que tarda en cargar, conversiones caen 7% según datos de Certificates.dev. En apps empresariales o e-commerce, eso es plata en efectivo.
Métricas de rendimiento web a monitorear
No mirés el reloj del browser. Mirá estas tres métricas, que son las que importan:
LCP (Largest Contentful Paint): cuánto tarda en pintar el contenido principal (imagen grande, título, lo que el usuario ve primero). Objetivo: menos de 2.5 segundos. En Vue, LCP sube si hacés rendering síncrono de 1000 elementos en el mount.
INP (Interaction to Next Paint): lag entre que el usuario hace click y el frame siguiente se renderiza. Objetivo: menos de 200ms. Acá Vue sufre si cada click corre un computed property que recalcula el estado global.
CLS (Cumulative Layout Shift): cuánto se mueve el layout mientras cargas. Es molesto. Evitalo reservando espacio para imágenes (aspect ratio CSS) y skeletons.
Herramientas: Vue.js Performance Guide oficial (donde Evan You y el equipo documentan patrones). Chrome DevTools Performance tab (grabás una sesión y ves cada frame). Vue DevTools extensión (inspeccionás componentes y ves si re-renderizan sin razón).
Code splitting y lazy loading: el primer paso
El cuello de botella número uno: el bundle es gigante.
Imaginate que tu aplicación tiene 5 rutas. El usuario entra en la home, pero estás enviando el código de todas las 5 rutas (+ librerías de las rutas que no va a visitar). Es un derroche. Más contexto en ejecutar agentes locales sin APIs externas.
Solución: lazy loading a nivel de rutas. En Vue Router, en vez de:
import Home from './views/Home.vue'
Hacés:
const Home = () => import('./views/Home.vue')
Resultado: Webpack automáticamente corta ese archivo en un chunk separado. El usuario descarga solo el código de la ruta que visita. Primera carga cae 60%, navegación entre rutas cae 30-50%.
Lo mismo aplica para componentes pesados (editores WYSIWYG, gráficos grandes). defineAsyncComponent() en Vue 3 es tu amigo. Envolvés un componente pesado, Vue lo descarga solo cuando es necesario, con loading fallback mientras tanto (spinner, esqueleto, lo que quieras).
Optimizar reactividad sin sacrificar performance
Vue.js es reactivo. Si el valor de una variable cambia, los componentes que la usan se re-renderizan automáticamente. Eso es genial (no necesitás jQuery para actualizar el DOM). Eso es terrible si tu estado es un objeto anidado infinito que todo reactivo se vuelve.
Ojo con esto: si metés reactive({ data: enormObject }) donde enormObject tiene 1000 propiedades (porque viene de un API), Vue crea una Proxy para cada una. El cambio en una propiedad requiere chequear todas las demás. Es lento.
shallowRef y shallowReactive: le decís a Vue “este objeto cambia, pero sus propiedades internas no”. En vez de vigilar 1000 propiedades, Vue vigila 1 (el objeto). Mejora de 40-65% en re-render speed según benchmarks.
Estructura normalizada: en lugar de anidación profunda:
{ user: { profile: { settings: { theme: 'dark' } } } }
Hace:
{ userTheme: 'dark', userName: '...' }
Flat. Vue.js sabe cómo optimizar objetos simples. Además, cuando hacés mutaciones, pasa más rápido (sin piletear en 5 niveles de nesting).
Rendering eficiente: v-if vs v-show, keys y v-memo
Esto parece boludo (voseo justificado). Pero es donde más gente se manda cagadas:
v-if: borra el elemento del DOM cuando condición es false. Rápido de ver (no está ahí). Lento de cambiar de estado (destruye y recrea el elemento).
v-show: oculta el elemento con CSS (display: none). El elemento sigue en el DOM. Rápido de cambiar de estado, más lento en el navegador. Tema relacionado: consideraciones de seguridad en repositorios.
Regla práctica (la verdad es que funciona): v-show para toggles que pasan 60+ veces por segundo (filtros en tiempo real, validación en cada keystroke). v-if para cambios raros (pestañas, modales, secciones que abren una vez cada sesión).
Keys en v-for: esto es crítico. Si hacés:
<div v-for="item in items">
Sin key, Vue recicla el mismo elemento DOM para cada item. Eso es un desastre si el elemento tiene estado interno (un input con valor, un checkbox marcado, animaciones). Siempre metele key único:
<div v-for="item in items" :key="item.id">
v-memo: (Vue 3.2+) cachea un componente. Si le pasás las mismas props, no re-renderiza. Útil para listas donde la mayoría de elementos no cambian.
VueSchool documentó que v-memo correctamente usado en una lista de 1000 elementos reduce re-renders 70-80%.
Prefetching y estrategias de caché de recursos
El usuario está en la home. Probablemente vaya a la ruta /dashboard. ¿Qué hacés? Precargas el código de /dashboard en background.
Técnicas (todas en HTML head):
DNS prefetch: resuelve el dominio antes de que el usuario le cliquee. Si tu app llama a api.example.com, avísale al browser que lo resuelva ya:
<link rel="dns-prefetch" href="https://api.example.com">
Preload: descarga un recurso (CSS, JS, fuente) que pronto va a necesitarse:
<link rel="preload" href="/dashboard.chunk.js" as="script">
Module preload: preload específico para módulos ES6:
<link rel="modulepreload" href="/dashboard.chunk.js">
Caché de datos: si un API endpoint no cambia frecuente (lista de países, configuración global), cachéalo en localStorage o sessionStorage. Request siguiente es instantáneo.
Según MetaDesign Solutions, prefetch + preload suman 30-50% en velocidad de navegación.
Herramientas y monitoreo en tiempo real
No optimices a ciegas. Primero medí. Después arreglá.
Vue DevTools: extensión de Chrome/Firefox. Abrís DevTools, pestañña “Vue”. Ves cada componente, qué data tiene, cuándo se re-renderiza, cuánto tiempo tarda. Si un componente re-renderiza 1000 veces por segundo sin razón, acá lo ves.
Webpack Bundle Analyzer: herramienta NPM que visualiza tu bundle. Te muestra qué librerías ocupan más espacio. Muchas veces descubrís que importaste una librería de 200KB sin quererlo. Ya lo cubrimos antes en herramientas modernas para acelerar desarrollo.
Chrome DevTools Performance tab: grabás una sesión de usuario (30 segundos), Vue reproduce cada frame. Ves dónde está el cuello de botella (JavaScript, rendering, layout).
Lighthouse: audit automático. Te da puntuación de performance, accesibilidad, SEO. Recomendaciones concretas de qué optimizar primero.
Tabla comparativa de estrategias según caso de uso
| Escenario | Estrategia principal | Herramienta | Mejora esperada |
|---|---|---|---|
| App lanza lentamente | Code splitting + lazy routes | Webpack Bundle Analyzer | 60% LCP |
| Clicks lentos, lag al typear | shallowRef + estructura normalizada | Vue DevTools | 40-65% INP |
| Listas de 1000+ elementos | v-memo + virtual scrolling | Chrome Performance | 70-80% re-renders |
| Navegación entre rutas lenta | Prefetch + preload | Lighthouse | 30-50% tiempo |
| Bundle demasiado grande | Tree shaking + eliminar deps | Bundle Analyzer | 20-40% bundle |

Errores comunes que frenan el rendimiento
1. Computeds o watchers que corren en cada frame
Escribís un computed que filtla una lista gigante cada vez que algo cambia. La lista tiene 10,000 elementos. El computed corre 60 veces por segundo (frame rate del browser). Estás procesando 600,000 elementos por segundo. Es un desastre.
Fix: cachea el resultado. Si los datos no cambiaron, devuelve el resultado anterior (memoización manual). O usá shallowRef para que el computed corra solo cuando cambia el dato específico que importa.
2. Props anidadas sin keys en v-for
Mandás una lista de objetos a un componente hijo. El componente hijo itera con v-for sin key. Cuando la lista se reordena, Vue reasigna el mismo componente DOM a items diferentes. Animaciones se rompen, estado interno del componente se pierde (inputs con valor, dropdowns abiertos).
Fix: siempre key único (ID del item es lo mejor). :key=”item.id”.
3. Imports globales gigantes sin tree shaking
Hacés `import moment from ‘moment’`. La librería entera (67KB) entra en tu bundle aunque uses solo dateFormat(). Moment es legacy anyway.
Fix: usá date-fns, day.js (5KB) o built-in Intl API. O en Webpack, configura `sideEffects: false` en package.json de la lib para permitir tree shaking.
Preguntas Frecuentes
¿Cuál es la diferencia entre v-if y v-show en Vue para rendimiento?
v-if destruye el elemento del DOM cuando es false, v-show solo lo oculta con CSS. v-if es rápido para ver (no ocupa espacio en el DOM), v-show es rápido para cambiar de estado. Usá v-show si toggleas más de 60 veces por segundo, v-if si es esporádico.
¿Cómo implementar lazy loading en Vue.js?
En Vue Router, cambía `import Home from ‘./Home.vue’` por `const Home = () => import(‘./Home.vue’)`. Webpack automáticamente crea un chunk separado. En componentes, usá `defineAsyncComponent()` para cargar componentes pesados bajo demanda. Ambos mejoran LCP 40-60%. Te puede servir nuestra cobertura de modelar tu infraestructura como código.
¿Por qué mi aplicación Vue es lenta y cómo arreglarlo?
Primero: medí con Vue DevTools + Chrome Performance. Busca componentes que re-renderizan innecesariamente, computeds que corren cada frame, o un bundle gigante. Los problemas comunes: falta code splitting, reactividad en objetos enormes, v-for sin keys, props mutables. Fijate la tabla comparativa de arriba para estrategia según tu caso.
¿Cuál es la mejor forma de reducir el tamaño del bundle en Vue?
1) Code splitting por rutas (lazy import en Vue Router). 2) Tree shaking en webpack (importa solo lo necesario). 3) Reemplaza librerías pesadas (moment → day.js, lodash → pequeñas utils). 4) Usa Webpack Bundle Analyzer para ver qué ocupa espacio. Combinadas, reducen 40-60% típicamente.
¿Cómo optimizar el rendimiento de una aplicación Vue.js?
Según Dev.to, el roadmap es: 1) LCP (code splitting + preload). 2) INP (shallowRef + estructura normalizada). 3) CLS (reserva espacio, skeletons). 4) Monitorea con Vue DevTools. El impacto máximo viene de las primeras tres. No pierdas tiempo optimizando cosas que no miden.
Plan de implementación: de proyecto a producción
Tenés una app vue que funciona pero es lenta. Acá cómo hacerlo rápido sin reescribir todo:
Semana 1 — Medir y priorizar: Corrés Lighthouse. Notas que LCP es 5 segundos. Abrís Vue DevTools. Ves que los componentes de la home se re-renderizan 100 veces en los primeros 3 segundos. Prioridad 1: code splitting.
Semana 2 — Code splitting: Movés a lazy loading en Vue Router. Ya tuviste una mejora 40%. LCP cae a 3 segundos.
Semana 3 — Reactividad: Identificás que un computed corre cada frame filtrando una lista de 5000 elementos. Cambias a shallowRef + memoización. INP mejora 50%.
Semana 4 — Preload y caching: Agregas prefetch para rutas que el usuario probablemente visite. Cacheás datos de APIs que no cambian. Navegación es ahora casi instantánea.
Total: LCP de 5s a 1.5s, INP de 300ms a 100ms. Conversiones suben. Ranking Google sube. Ganaste.
Conclusión
Vue.js es un framework optimizable. Si es lento, es porque el código no está optimizado, no porque Vue sea malo. Los wins rápidos son tres: code splitting (lazy routes), reactividad selectiva (shallowRef) y rendering eficiente (v-if vs v-show, keys, v-memo).
La mayoría de apps mejora 40-70% en Core Web Vitals con esas tres movidas. No necesitás reescribir nada. Necesitás medir, priorizar y aplicar estrategias en orden de impacto.
Si tu app tiene componentes pesados, dashboards complejos o muchos datos, la optimización rendimiento Vue.js no es un bonus, es obligatorio. Empezá con Vue DevTools hoy. Medí. Después optimizá. Te va a sorprender cuánto cambia con cambios pequeños bien hechos.






