Cómo construimos sitios web rápidos: una guía de campo de los Core Web Vitals
Los Core Web Vitals no son un marcador, son una promesa a tus usuarios. Aquí está exactamente cómo construimos sitios web rápidos en Innovation T, desde la estrategia de imágenes hasta la activación condicional de WebGL en dispositivos capaces.
Por Innovation T Team
Un sitio web lento pierde a la gente antes siquiera de tener la oportunidad de exponer sus argumentos. Alguien toca tu enlace en un teléfono Android de gama media con una conexión inestable, espera, ve que el diseño salta por todas partes, toca un botón que no hace nada durante medio segundo y se marcha. Ningún texto ingenioso sobrevive a esa experiencia. En Innovation T tratamos el rendimiento como una característica del producto, no como una tarea de limpieza, y los Core Web Vitals son el lenguaje que Google nos da para medirlo.
Esta es la guía de campo que realmente usamos cuando construimos. Explica qué significan las métricas en términos sencillos y luego te ofrece las tácticas concretas a las que recurrimos en proyectos reales.
Qué miden realmente las métricas
Los Core Web Vitals son tres métricas centradas en el usuario, más una métrica de laboratorio que te ayuda a encontrar problemas antes que tus usuarios. Olvida los acrónimos por un momento y piensa en lo que siente el usuario.
LCP (Largest Contentful Paint) responde a una pregunta sencilla: ¿cuánto tarda en aparecer el elemento principal de esta página? Ese "elemento principal" suele ser una imagen de héroe, un titular o un gran bloque de texto. Si tu LCP es de 4 segundos, tu visitante mira fijamente una pantalla casi en blanco durante 4 segundos. Google considera que 2,5 segundos o menos es un buen resultado.
INP (Interaction to Next Paint) mide la capacidad de respuesta. Cuando alguien toca, hace clic o escribe, ¿cuánto tarda la página en reaccionar de forma visible? INP reemplazó a la antigua métrica First Input Delay porque observa todas las interacciones a lo largo de la visita, no solo la primera. Un botón lento, un menú que se abre con un instante de retraso, un campo de formulario que se traba: eso es un mal INP. Un buen resultado es de 200 milisegundos o menos.
CLS (Cumulative Layout Shift) mide la estabilidad visual. Es la frustración de leer un párrafo y verlo saltar porque una imagen o un anuncio se cargó encima, o de intentar tocar un botón que de repente se desliza de debajo de tu dedo. Un buen CLS es de 0,1 o menos.
TBT (Total Blocking Time) es la contraparte de laboratorio de INP. Mide cuánto tiempo estuvo bloqueado el hilo principal e incapaz de responder durante la carga de la página. Verás el TBT en Lighthouse y otras herramientas de laboratorio. Un TBT alto casi siempre predice un mal INP en el campo, por eso lo usamos como una alerta temprana durante el desarrollo.
El patrón aquí importa. LCP tiene que ver con la carga, INP y TBT con la interactividad, y CLS con la estabilidad. La mayor parte del trabajo de rendimiento se reduce a enviar menos al navegador y a hacer menos trabajo en el hilo principal. Todo lo que sigue es una versión de esas dos ideas.
Estrategia de imágenes: normalmente la mayor ganancia
Las imágenes son lo más pesado en la mayoría de las páginas, y la imagen de héroe es con frecuencia el elemento LCP, así que es por aquí donde empezamos.
- Sirve formatos modernos. AVIF y WebP son drásticamente más ligeros que JPEG o PNG con la misma calidad. Servimos AVIF con una alternativa en WebP y solo recurrimos a formatos más antiguos cuando realmente no hay más remedio.
- Ajusta las imágenes a su tamaño de visualización y entrega variantes adaptables. Usa
srcsetysizespara que un teléfono descargue una imagen del tamaño de un teléfono, no un recurso de escritorio de 2000 píxeles reducido en el navegador. - Define siempre
widthyheightexplícitos (o unaspect-ratioen CSS). Esto reserva el espacio antes de que se cargue la imagen y es la solución individual más eficaz para el CLS. - Prioriza la imagen LCP y carga el resto de forma diferida. Añade
fetchpriority="high"al héroe yloading="lazy"a todo lo que quede por debajo del pliegue, para que las imágenes fuera de pantalla no compitan por el ancho de banda durante el primer renderizado crítico. - Considera una sugerencia de precarga (preload) para la imagen de héroe, de modo que el navegador comience a obtenerla antes de terminar de analizar el CSS.
Acertar con la imagen de héroe a menudo basta por sí solo para bajar el LCP por debajo de la marca de 2,5 segundos. La misma disciplina se aplica al vídeo: usa una imagen de póster y nunca reproduzcas automáticamente un vídeo de fondo pesado en móvil.
Carga de fuentes: detén el texto invisible
Las fuentes web son un asesino silencioso del LCP y del CLS. Una página espera a una fuente personalizada, no muestra nada (o muestra un texto alternativo que luego se recompone) y el usuario lo paga.
- Añade
font-display: swappara que el texto se muestre de inmediato con una fuente alternativa y cambie a la fuente web cuando llegue. Los usuarios pueden leer mientras se carga la fuente. - Aloja tus fuentes en tu propio servidor en lugar de traerlas de un tercero. Elimina una conexión adicional y te da control sobre la caché.
- Precarga el uno o dos archivos de fuente críticos para que empiecen a descargarse pronto.
- Reduce las fuentes (subsetting) a los caracteres y grosores que realmente utilizas. Entregar todos los grosores de una familia cuando usas dos es puro desperdicio.
- Elige una fuente alternativa con métricas similares, o ajústala con
size-adjust, para que el cambio no provoque una recomposición visible. Eso protege el CLS.
Reducir el JavaScript del hilo principal
El JavaScript es donde van a morir un buen INP y un buen TBT. Cada script que el navegador tiene que analizar, compilar y ejecutar ocupa el hilo principal, y mientras ese hilo está ocupado no puede responder a los toques. Esta es el área más difícil y más valiosa de dominar.
- Envía menos. Audita tu bundle y elimina las dependencias que no necesitas. Una biblioteca de fechas, un kit de interfaz enorme usado para un solo componente, tres bibliotecas de utilidades que se solapan: esto se acumula rápido.
- Divide el código (code splitting) y carga de forma diferida. Carga el JavaScript de una ruta o un componente solo cuando se necesita, no todo de antemano. Una ventana modal que se abre al hacer clic no necesita estar en el bundle inicial.
- Aplaza los scripts no críticos. Las herramientas de analítica, los widgets de chat y las etiquetas de marketing deberían cargarse después de que la página sea interactiva, no competir con ella. Usa
defero cárgalos en inactividad (on idle). - Fragmenta las tareas largas. Cualquier tarea de más de 50 milisegundos bloquea la interacción. Divide el trabajo pesado y cede el control al hilo principal para que el navegador pueda responder a la entrada entre fragmentos.
- Prefiere la plataforma. Buena parte de aquello para lo que la gente instala bibliotecas (validación de formularios, animación sencilla, formato de fechas) el navegador ya lo hace de forma nativa. Construimos páginas de alta conversión con menos código, un tema que abordamos en nuestra guía sobre la anatomía de una landing page de alta conversión.
Activación condicional de bibliotecas pesadas de WebGL y animación
Aquí es donde la experiencia práctica separa los buenos sitios de los que van a trompicones. Los visuales ricos, las escenas WebGL y la animación basada en física lucen espectaculares en un portátil de gama alta y convierten un teléfono económico en una presentación de diapositivas. La respuesta no es eliminarlos, sino servirlos de forma condicional.
- Ejecuta WebGL pesado solo cuando hay una GPU real presente. Antes de montar una escena 3D costosa, detectamos el contexto de renderizado y comprobamos el renderizador informado. En un renderizador por software o en un dispositivo que falla una prueba rápida de capacidad, recurrimos a una imagen estática o a una versión ligera en CSS en lugar de a un bucle WebGL completo.
- Respeta al usuario. Honra la consulta de medios
prefers-reduced-motiony omite la animación no esencial para quienes lo piden. Omite también los efectos pesados cuando el dispositivo informa pocos núcleos de CPU o cuando la sugerencia Save Data está activada. - Lleva la animación a CSS siempre que puedas. Las animaciones de transformación y opacidad en CSS se ejecutan en el hilo del compositor y son baratas. Un efecto al pasar el ratón, un fundido, un deslizamiento sutil: esto pertenece al CSS, no a una biblioteca de animación de JavaScript que se ejecuta en el hilo principal.
- Limita tu bucle de renderizado. Si debes ejecutar un bucle de fotogramas de animación, pon un tope a la tasa de fotogramas y pausalo por completo cuando el elemento se desplace fuera de la vista o la pestaña esté oculta. Un bucle que repinta a toda velocidad para un canvas fuera de pantalla es puro desperdicio que aparece como un mal INP.
- Carga la biblioteca pesada solo cuando el efecto es realmente visible. Usa un intersection observer para que el bundle de WebGL o de animación se descargue cuando el usuario se desplaza cerca de él, no en la carga inicial.
Carga diferida, caché y CDN
La última capa consiste en no hacer el trabajo dos veces y no servir desde lejos.
- Carga de forma diferida el contenido por debajo del pliegue: imágenes, iframes, incrustaciones y componentes pesados. El navegador tiene
loading="lazy"nativo para imágenes e iframes, y un intersection observer cubre todo lo demás. - Guarda en caché de forma agresiva. Los recursos estáticos con nombres de archivo con hash de contenido pueden guardarse en caché durante un año, porque un cambio en el archivo cambia el nombre del archivo. Establece cabeceras
Cache-Controllargas para esos y más cortas para el HTML. - Usa una CDN. Servir recursos desde una ubicación de borde (edge) cercana a tu usuario recorta la latencia directamente, lo que ayuda al LCP. Una CDN también absorbe los picos de tráfico y descarga trabajo de tu servidor de origen.
- Comprime todo. Brotli para los recursos de texto supera a gzip, y debería estar activado de forma predeterminada a nivel de servidor o de CDN.
- Reduce el tiempo de respuesta del servidor. Un primer byte lento envenena todas las métricas posteriores. Guarda en caché las páginas renderizadas cuando puedas y mantén el trabajo de base de datos fuera de la ruta crítica. Cuando diseñamos las API que hay detrás de estas páginas, optimizamos precisamente para esto, un tema en el que profundizamos en diseñar API que los desarrolladores adoran.
La lista de verificación de rendimiento
Esta es la lista numerada que repasamos antes de lanzar.
- Confirma el elemento LCP (normalmente la imagen de héroe o el titular) y dale carga prioritaria.
- Sirve AVIF o WebP, dimensionado de forma adaptable con
srcsetysizes. - Define dimensiones explícitas o
aspect-ratioen cada imagen e incrustación de medios para eliminar el desplazamiento del diseño. - Carga de forma diferida cada imagen, iframe y componente pesado por debajo del pliegue.
- Aloja las fuentes en tu propio servidor, redúcelas (subset), precarga los archivos críticos y usa
font-display: swap. - Audita el bundle de JavaScript y elimina o reemplaza las dependencias pesadas.
- Divide el código por ruta y carga de forma diferida los componentes que no se necesitan en el primer renderizado.
- Aplaza los scripts de analítica, chat y marketing hasta después de la interactividad.
- Fragmenta cualquier tarea del hilo principal de más de 50 milisegundos y cede el control entre fragmentos.
- Activa WebGL solo tras una comprobación de GPU real, con una alternativa estática para los dispositivos débiles.
- Lleva las animaciones a transformaciones y opacidad en CSS, y honra
prefers-reduced-motion. - Limita y pausa los bucles de renderizado cuando estén fuera de pantalla o cuando la pestaña esté oculta.
- Establece cabeceras de caché largas en los recursos estáticos con hash y más cortas en el HTML.
- Sirve a través de una CDN con la compresión Brotli activada.
- Mide con herramientas de laboratorio (Lighthouse, TBT) durante el desarrollo, y luego valida con datos de campo (LCP, INP, CLS reales) tras el lanzamiento.
Ese último punto es el que la gente se salta. Las puntuaciones de laboratorio te dicen dónde están los problemas, pero solo los datos de campo te dicen lo que experimentan tus usuarios reales en sus dispositivos y redes reales. Construimos para el laboratorio y verificamos en el campo.
La rapidez es una decisión de diseño que tomas a propósito, una y otra vez, en cada capa. Hazlo bien y las métricas se cuidan solas, porque no son más que mediciones de un sitio que respeta a la persona que lo usa.
Si tu sitio se siente lento y no estás seguro de adónde se va el tiempo, ese es exactamente el tipo de problema que nos gusta. Echa un vistazo a nuestros servicios o ponte en contacto y te ayudaremos a construir algo rápido.
¿Listo para construir con Innovation T?
Ya se trate de seguridad, crecimiento o ingeniería, nuestro equipo puede ayudarte a lograrlo con calidad.