Optimización de Vue.js y Nuxt.js: consejos y trucos
Vue.js es rápido. Pero solo si lo usas correctamente.
Un visitante espera que se cargue tu sitio web, pero en tres segundos se va a otro lado. Lamentablemente, esto no es ciencia ficción; es la realidad de muchos sitios modernos, incluso aquellos construidos con frameworks como Vue.js o Nuxt.js.
Comencemos aclarando de qué trataremos aquí:
- Vue.js es uno de los frameworks de JavaScript más populares para desarrollar aplicaciones web.
- Nuxt.js es un meta framework que permite ejecutar Vue.js en el servidor, mejorando así el rendimiento, entre otras cosas.
La optimización adecuada no es solo una delicadeza técnica para los programadores. Es una inversión que se traduce en mayores conversiones, mejores posiciones en los motores de búsqueda y usuarios más satisfechos.
Clientes de PageSpeed.ONE como Dr. Max o Airstop que utilizan Vue.js logran mejores resultados gracias a una optimización adecuada.
¿Por qué es vital la velocidad para los sitios web?
Quizás te preguntes: «¿Y qué si el sitio tarda un segundo más en cargar?» La realidad es dura y los números no mienten. La velocidad del sitio tiene un impacto directo y medible en tu negocio. Veamos algunos ejemplos:
-
Google midió que si una página cumple con los Web Vitals, hay un 24% menos de probabilidad de que los usuarios se vayan antes de que se cargue.
-
El ratio de conversión de un e-commerce disminuye en promedio un 0,3% con cada segundo adicional de carga.
-
La velocidad es un factor de ranking directo para SEO en el algoritmo de Google.
La velocidad no es un lujo, es una necesidad. Y cada milisegundo cuenta. Estos números son aún más cruciales para sitios construidos con frameworks JS modernos como React o Vue.js.
¿Por qué? Porque casi siempre cargan y ejecutan más JavaScript que los sitios tradicionales y deben pasar por un proceso de inicialización más complejo.
Pero no te preocupes. Con el enfoque correcto, tu sitio web Vue.js puede ser más rápido que muchas páginas estáticas.
¿Vue.js es intrínsecamente lento? Distingamos mitos de realidades
Es común escuchar que Vue.js y otros frameworks modernos son intrínsecamente lentos. Sí, más JavaScript significa más trabajo durante el proceso de optimización de velocidad. Sin embargo, Vue.js está diseñado para el rendimiento, y los sitios construidos con él pueden ser muy rápidos.
Los problemas de rendimiento suelen surgir por errores humanos, no por el framework en sí:
-
Arquitectura incorrecta
Usar una Single Page Application (SPA) donde sería mejor el renderizado del lado del servidor. -
Falta de optimización
Ignorar las mejores prácticas. Algunas de ellas las indicamos en este texto. -
Pruebas solo en dispositivos rápidos
Los desarrolladores a menudo no ven los problemas reales que enfrentan los usuarios comunes e ignoran la llamada Performance Inequality Gap.
Vue.js puede ser rápido por sí mismo. La clave es usarlo correctamente y saber cuándo aplicar cada técnica.
Cómo saber si tu sitio web Vue.js está cojeando
Puede que pienses que tu sitio está bien porque te parece rápido. Pero, ¿lo estás probando correctamente?
Mide la velocidad de tu sitio en PageSpeed.ONE.
Core Web Vitals: Tres pilares de la velocidad
Core Web Vitals son tres métricas clave que determinan si tu sitio web es rápido desde la perspectiva del usuario:
| Métrica | Significado | Valor recomendado |
|---|---|---|
| Largest Contentful Paint (LCP) | Velocidad de carga. Tiempo de carga del elemento visible más grande en la página. | ≤ 2,5 segundos |
| Interaction to Next Paint (INP) | Velocidad de interacción. Tiempo de respuesta a las acciones del usuario (clics, toques). | ≤ 200 milisegundos |
| Cumulative Layout Shift (CLS) | Estabilidad del diseño. Estabilidad del diseño visual de la página. | ≤ 0,1 |
Siete pasos para un sitio más rápido en Vue.js
Ahora viene la parte más importante. Veamos algunos consejos básicos para acelerar tu sitio web Vue.js.
1. Arquitectura adecuada: SSR y SSG en lugar de SPA puras
Las siglas suenan complicadas, pero el concepto es simple. En lugar de que tu sitio espere a que se descargue y ejecute el JavaScript, envía al usuario directamente el código HTML terminado.
Exagerando un poco, es como la diferencia entre recibir un almuerzo ya preparado o tener que esperar a que alguien lo cocine en la mesa frente a ti.
Vamos con las siglas:
-
SPA (Single Page Application) es un sitio que carga la mayoría de las cosas de una vez al principio y luego actúa como si todo se manejara en el dispositivo del cliente sin recarga, pero a costa de un inicio muy lento y otros inconvenientes. Te cocinan el almuerzo en la mesa. Hoy en día, es un enfoque anticuado.
-
Server Side Rendering (SSR) significa que el servidor genera el código HTML terminado para cada página. Así, el usuario ve el contenido de inmediato mientras el JavaScript interactivo se carga en segundo plano. Eso es lo que queremos.
-
Static Site Generation (SSG) va un paso más allá. Los archivos HTML se generan previamente (en un proceso interno de desarrollo denominado build) y se sirven como archivos estáticos. Es la variante más rápida posible. Sin embargo, no es adecuada para e-commerces y otros sitios más dinámicos.
-
Enfoque híbrido combina ambos métodos según el tipo de página: páginas estáticas como publicaciones de blog como SSG, dinámicas como SSR. Considera si puedes usar esto para tu sitio web.
Veamos una configuración esquemática de SSR para la parte del servidor de Vue.js, que se llama Nuxt.js:
// nuxt.config.ts o nuxt.config.js para SSR
export default defineNuxtConfig({
// Activar renderizado del lado del servidor
ssr: true,
nitro: {
prerender: {
// Pre-generación de páginas estáticas
routes: ['/sobre-nosotros', '/contacto', '/blog']
}
}
});
Si tu sitio web es sensible a la velocidad de carga, evita un SPA completamente del lado del cliente. Considera combinaciones de SSR y SSG.
2. Renderizado progresivo: Lazy loading como salvación
Imagina que estás construyendo una casa. No llevas todos los ladrillos a la vez, sino poco a poco según se necesiten. De la misma manera debería comportarse tu sitio web Vue.js.
¿Cómo lograrlo?
-
Lazy loading de componentes significa que los componentes se cargan solo cuando realmente se necesitan. Por lo general, se refiere a componentes que el usuario no ve en la primera pantalla o que utiliza solo ocasionalmente.
-
Hidratación progresiva es el proceso en el que el JavaScript se va «conectando» al HTML generado por el servidor. Así, el usuario ve el contenido de inmediato, pero la interactividad se añade progresivamente donde se necesita.
-
Code splitting divide automáticamente tu código en partes más pequeñas según las páginas o funciones. En lugar de descargar un archivo grande, se descargan gradualmente solo las partes necesarias.
Ejemplo de carga diferida de componentes:
// Utiliza lazy loading
const HeavyChart = defineAsyncComponent(() => import('./HeavyChart.vue'));
// Con estado de carga (por ejemplo, un spinner)
const HeavyTable = defineAsyncComponent({
loader: () => import('./HeavyTable.vue'),
loadingComponent: LoadingSpinner,
delay: 200
});
Carga solo lo que se ve. El resto puede esperar.
Tenemos un artículo completo sobre lazy loading en términos generales.
3. Tamaño del bundle: Menos JavaScript, más velocidad
Cada kilobyte de JavaScript necesita ser descargado, parseado y ejecutado. En dispositivos lentos o conexiones débiles, esto puede llevar una eternidad. Por eso es importante mantener el tamaño de tu bundle de JavaScript lo más pequeño posible. ¿Cómo?
-
Tree shaking es un proceso que elimina automáticamente el código no utilizado de tu bundle. Los bundlers modernos como Webpack o Vite lo hacen automáticamente, pero debes ayudarles importando de la manera correcta.
-
Auditoría de dependencias significa revisar regularmente qué bibliotecas realmente necesitas. A menudo sucede que en el proyecto quedan bibliotecas que ya no utilizas, pero que siguen aumentando el tamaño del bundle.
-
Compresión de archivos puede reducir el tamaño del bundle hasta en un 70%. La compresión Brotli moderna es incluso más eficaz que el tradicional Gzip.
// Incorrecto – importa toda la librería (varios MB)
import _ from 'lodash';
// Correcto – importa solo la función necesaria (varios kB)
import { debounce } from 'lodash-es';
// 💡 Aún mejor – implementación sencilla propia
const debounce = (fn, delay) => {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
};
Un consejo sencillo: la herramienta bundlephobia.com te muestra el tamaño de cada dependencia y te recomienda alternativas.
Cada kilobyte cuenta. Mantén tu bundle a dieta.
4. Optimización para mejorar INP: Respuestas rápidas al clic
Interaction to Next Paint (INP) mide cuán rápido responde el sitio a las acciones del usuario. Si el usuario hace clic en un botón y no pasa nada, o pasa lentamente, nuestro querido usuario se frustra.
El problema más común son las operaciones costosas realizadas en el hilo principal del navegador, conocidas como tareas largas (medibles con la métrica JS Long Tasks (JSLT) o sintéticamente con la métrica TBT). Cuando tu JavaScript procesa mucho, el navegador no puede responder a los clics mientras tanto.
La hidratación, es decir, la activación de la aplicación, puede sobrecargar al navegador e imposibilitar las interacciones a los usuarios. Este problema lo solucionamos en el proyecto Airstop.cz.
¿Qué hacer al respecto?
-
Utiliza la hidratación diferida. Especialmente en componentes donde es claro que el usuario no los activará de inmediato. Estos típicamente pueden ser menús, modales, filtros, pie de página, etc.
-
Debouncing y throttling son técnicas que limitan el número de llamadas a funciones durante una acción repetida rápidamente. Típicamente al escribir en un campo de búsqueda o al desplazarse.
-
Reduce el DOM. La estructura dinámica de HTML (DOM) es fundamental. Manténla lo más pequeña posible, idealmente a 3,000 nodos DOM o menos.
Debouncing para búsqueda:
// Debouncing para búsqueda – responde solo después de 300 ms desde la última pulsación
import { debounce } from 'lodash-es';
const searchProducts = debounce((query) => {
// La búsqueda se activa solo después de una pausa
}, 300);
// 🖱️ Throttling para scroll – se activa como máximo una vez cada 100 ms
import { throttle } from 'lodash-es';
const handleScroll = throttle(() => {
// Optimización del listener de scroll
}, 100);
Operaciones pesadas como filtrado de grandes datos o cálculos complejos deben trasladarse al servidor a través de llamadas API.
Mantén el hilo principal del navegador libre. El usuario debe sentir una respuesta inmediata.
5. Virtualización de listas: Miles de elementos sin ralentización
Si tienes una lista con miles de productos, artículos o comentarios, no puedes renderizarlos todos a la vez. Eso ralentizaría el sitio a niveles intolerables.
La virtualización significa que solo renderizas elementos visibles más un pequeño buffer alrededor. Al desplazarte, los elementos se intercambian dinámicamente. Es como leer un libro: no lees todas las páginas a la vez, solo la actual.
Existen bibliotecas listas para Vue.js que implementan la virtualización por ti. Las más populares son vue-virtual-scroller o vue-virtual-scroll-grid.
La virtualización puede mejorar el rendimiento de la lista en cientos de porcentajes, especialmente en dispositivos móviles con rendimiento limitado.
Renderiza solo lo que el usuario ve. Miles de elementos pueden esperar.
6. Manejo adecuado de imágenes: Formatos modernos y carga diferida
Las imágenes en algunos sitios web constituyen la mayor parte del volumen de datos que deben cargarse. La optimización adecuada de imágenes puede ser la manera más efectiva de acelerar un sitio web.
-
Formatos modernos como WebP y AVIF ofrecen una compresión un 25-50% mejor que el JPEG tradicional, manteniendo la calidad. Los navegadores modernos ya soportan WebP y AVIF.
-
Imágenes responsivas significan proporcionar las dimensiones correctas para diferentes dispositivos. ¿Por qué cargar una imagen de 2000px de ancho en un teléfono móvil con una pantalla de 400px de ancho?
-
Carga diferida de imágenes significa que las imágenes se cargan solo cuando entran en el campo de visión del usuario. Esto acelera significativamente la carga inicial de la página.
-
Imágenes de marcador de posición evitan cambios de diseño (saltos de contenido) durante la carga. Puedes usar miniaturas borrosas, fondos de color o loaders esqueleto. Sin embargo, úsalos con cuidado, ya que si se usan mal, pueden empeorar la velocidad.
Ejemplo en código – imágenes responsivas con carga diferida:
<!-- Imagen AVIF con fallback a WebP + carga diferida -->
<picture>
<source src="product-image.avif" type="image/avif" />
<img src="product-image.webp" loading="lazy" alt="Descripción del producto" width="800" height="600" />
</picture>
Optimiza las imágenes cuidadosamente, especialmente si son tu elemento LCP.
7. Perfilado: La medición es la base de la mejora
Sin medición, optimizas a ciegas. Puede que optimices algo que no es un problema en absoluto, mientras que pasas por alto el verdadero cuello de botella.
¿Qué herramientas utilizar además de lo básico absoluto, que es el monitoreo sintético y CrUX?
-
Panel de Rendimiento de Chrome DevTools te muestra dónde tu código pasa la mayor parte del tiempo. Puedes ver qué componentes se renderizan más lentamente o qué funciones sobrecargan la CPU. Más sobre la medición de Web Vitals en el navegador.
-
Vue DevTools proporciona métricas específicas de Vue.js: qué componentes se vuelven a renderizar, cuánto tiempo lleva su montaje o actualización.
-
Monitoreo de usuario real (RUM) sigue a usuarios reales en dispositivos reales con internet real. Las pruebas de laboratorio son importantes, pero el RUM muestra la realidad. Es el más preciso de los tres tipos de medición de velocidad.
Lo que no mides, no puedes mejorar.
Otros trucos para avanzados: CDN, prefetching y tecnologías modernas
Si has dominado lo básico, puedes avanzar. Aquí algunos consejos de optimización más allá de lo anterior:
-
Elige buena infraestructura y una Red de Entrega de Contenidos (CDN). Una CDN significa que tus archivos se cargan desde el servidor más cercano al usuario. Es como tener sucursales de una tienda en todas las ciudades en lugar de una sola central. Utiliza Cloudflare o AWS CloudFront.
-
Optimización del BFCache, es decir, los rápidos retornos a la página anterior, te puede traer buenos resultados con poco esfuerzo.
-
Speculation Rules API te ofrecen una predicción inteligente de navegación, pero su implementación es de alto nivel, cuidado con ello.
Éxitos de PageSpeed.ONE: resultados reales de la optimización
La teoría es bonita, pero ¿qué hay de la práctica? Hemos trabajado con varios proyectos Vue.js donde la optimización del rendimiento ha tenido un impacto significativo.
Uno de ellos es el sitio del vendedor de vacaciones Airstop.cz, donde ayudamos al equipo de desarrolladores de DesignDev a mejorar la experiencia del usuario durante un rediseño en progreso.
El proyecto todavía está en proceso, pero ya vemos mejoras en las métricas Core Web Vitals de decenas de porcentajes:
En Airstop.cz se puede ver que los proyectos en Vue.js pueden hacer grandes avances en velocidad. Y aún es temprano.
Con otro de nuestros clientes, las farmacias Dr. Max, ya tenemos las métricas LCP y CLS en verde y actualmente estamos trabajando en mejorar la interactividad (INP). Ejemplos de estas optimizaciones incluyen:
- Optimización de interacciones de usuario con loaders utilizando el método
nextTicken todo el sitio. - Aceleración de interacciones de usuario en búsquedas complejas a través de productos.
- Optimización de eventos desencadenados desde GTM (Google Tag Manager).
Cada proyecto es específico, pero los principios permanecen: sin optimización posterior al desarrollo, no se puede mantener la velocidad en un buen nivel. Lo más importante es comenzar midiendo e implementando cambios gradualmente.
Cómo te ayuda el monitoreo de PageSpeed.ONE
En nuestro monitoreo de velocidad PageSpeed.ONE puedes seguir las métricas Core Web Vitals en tiempo real e identificar problemas concretos. A menudo vemos en sitios Vue.js problemas con grandes bundles de JavaScript o hidratación lenta (el proceso en el que el JavaScript interactivo se conecta al HTML).
Seguimos la evolución de las métricas Core Web Vitals a largo plazo para nuestro cliente Dr. Max y sus competidores.
La medición es la base. Sin datos, optimizas a ciegas.
Nuestro PageSpeed.ONE monitoring PLUS ofrece estas ventajas:
- Monitoreo continuo de Core Web Vitals con datos CrUX y sintéticos.
- Comparación con la competencia en tu sector y otros datos de dominio.
- Análisis detallados de cada prueba.
- Vigilancia y alertas ante deterioros en el rendimiento con posibilidad de reacción rápida.
Recomendamos encarecidamente automatizar el monitoreo para que puedas concentrarte en las optimizaciones.
Monitoreo de Velocidad PLUS
Prueba nuestra aplicación de monitoreo gratis por un mes.
5 400 CZK al año por el sitio web. Factura, no necesitas tarjeta de crédito.
Conclusión: La velocidad como ventaja competitiva
La optimización de aplicaciones Vue.js no debería ser una acción puntual, sino un proceso continuo. Vue.js en sí no es lento; los problemas surgen por un uso incorrecto o una optimización insuficiente.
Comienza midiendo con Core Web Vitals, considera implementar SSR y optimiza gradualmente según nuestro listado. Recuerda que cada milisegundo cuenta y la velocidad puede ser tu ventaja competitiva.
¿No sabes qué hacer a continuación? No dudes en contactarnos.
El resultado de la optimización de Vue.js será un sitio más rápido, usuarios más satisfechos, mejores posiciones en los motores de búsqueda y, no menos importante, mayores ingresos.