Las aplicaciones Nuxt son rápidas por defecto y lentas por acumulación. Casi nada en un proyecto nuevo es un problema de rendimiento; los problemas llegan poco a poco, mediante decisiones que son razonables una a una. La mayor parte del trabajo consiste en detectarlas pronto, porque cada una es barata de evitar y cara de deshacer.

Elige el modo de renderizado deliberadamente

La primera decisión es la que más efecto tiene y suele tomarse por defecto en lugar de a propósito.

Este sitio pre-renderiza todas las rutas a HTML estático: ssr: true con un preset estático de Nitro. El contenido de marketing cambia a ritmo humano, así que no hay razón para que un servidor ensamble la misma página una y otra vez. Los rastreadores reciben marcado real, las etiquetas meta y los datos estructurados están en la primera respuesta, y el alojamiento es un CDN sin runtime que mantener caliente ni pagar.

Ese es el valor por defecto correcto para sitios con forma de contenido y el equivocado para una aplicación cuyo contenido es por usuario. Nuestras aplicaciones de producto renderizan de otra manera exactamente por eso. El fallo a evitar no es elegir uno u otro, sino aceptar el que venga por defecto y descubrir después que la mitad de las rutas necesitaban otra cosa, parcheando página a página.

Envía menos JavaScript

El mayor coste evitable en la mayoría de aplicaciones Vue son los componentes que se hidratan sin necesitarlo.

Un componente que renderiza marcado estático y nunca responde a una interacción no debería enviar su JavaScript al navegador. La hidratación diferida y los componentes de servidor de Nuxt existen para esto, y aplicarlos a los candidatos obvios — secciones de página, bloques de marketing, cualquier cosa bajo el pliegue que sea puramente presentacional — elimina de forma fiable una parte significativa del bundle.

El segundo coste evitable es el peso de las dependencias. Una librería de fechas importada para una sola llamada de formato, un set de iconos importado entero para seis iconos, un paquete de utilidades para algo que la librería estándar ya hace. Son pequeños por separado y dominantes en conjunto. Ejecutar un análisis del bundle de vez en cuando y preguntarse si cada una de las entradas más grandes se gana su tamaño es un ejercicio de veinte minutos que compensa repetidamente.

Imágenes y tipografías, una vez y bien

Las imágenes suelen ser los bytes más grandes de una página y los más fáciles de arreglar mecánicamente. Formatos modernos, dimensiones explícitas para evitar saltos de maquetación, carga diferida bajo el pliegue y tamaños responsivos para que un móvil no descargue un recurso de escritorio. @nuxt/image se encarga de esto si se usa de forma consistente; el fallo típico son unas pocas etiquetas <img> sueltas que se cuelan.

Las tipografías conviene resolverlas una vez y olvidarlas. Autoalojar en lugar de tirar de un origen de terceros, hacer subconjuntos con los caracteres realmente usados, precargar las fuentes que aparecen sobre el pliegue y usar font-display: swap para que el texto se muestre antes de que llegue la fuente. Una tipografía de display propia suele valer su coste; tres pesos de ella normalmente no.

Que la animación no cueste fotogramas

Nuestros sitios usan movimiento con bastante intensidad, lo que convierte esto en una restricción real y no teórica.

Animar transform y opacity y prácticamente nada más: esas son las propiedades que el compositor puede manejar sin layout ni pintado. Animar anchura, altura o posición fuerza trabajo de maquetación en cada fotograma y se nota de inmediato en móviles de gama media, que es lo que usa la mayoría de visitantes. Cuando un efecto necesita genuinamente animar algo caro, casi siempre se puede simular con una transformación sobre un elemento estructurado de otra forma.

Dos cosas hacen esto mantenible en lugar de una negociación por componente. Los keyframes y los tokens de easing viven en una sola hoja de estilos, así que el movimiento es consistente y los errores caros se detectan en un solo sitio. Y prefers-reduced-motion se respeta en todo el sitio: primero como requisito de accesibilidad y, de paso, como el presupuesto de fotogramas más barato que existe.

Mide lo que el usuario experimenta

Lighthouse es una herramienta útil de desarrollo y una mala descripción de producción. Se ejecuta en una máquina, en una red, con la caché vacía.

Los datos de campo de sesiones reales son los que dicen si el trabajo sirvió de algo — Largest Contentful Paint e Interaction to Next Paint en particular, porque corresponden a lo que alguien nota de verdad: cuánto tarda la página en estar ahí y si responde al tocarla. Que esos dos números se muevan es la única evidencia que importa, y con frecuencia no guardan relación con la puntuación de laboratorio que motivó el trabajo.