La Optimización de Web Vitals no es solo vanidad métrica; es una disciplina de ingeniería que busca minimizar la fricción cognitiva y tecnológica entre el usuario y el contenido, priorizando el Largest Contentful Paint (LCP) y la estabilidad visual sobre la interactividad innecesaria.


Vivimos en una era donde los desarrolladores envían 500KB de JavaScript solo para renderizar un texto estático. Es absurdo .

Cuando decidí reconstruir mi portafolio, me impuse una restricción draconiana: Zero Runtime JS (o lo más cercano posible). No quería un sitio que “se sintiera” rápido. Quería un sitio matemáticamente perfecto. Y quería ver ese color verde neón en las cuatro categorías de Lighthouse.

Aquí está el resultado final:

100
Performance
100
Accessibility
100
Best Practices
100
SEO

1. La Arquitectura: ¿Por qué Astro 5?#

La elección del framework define tu techo de rendimiento. Si eliges Next.js con el app router, empiezas la carrera con una mochila de piedras (el bundle de React).

Astro Islands es la clave. Esta arquitectura permite que el HTML sea estático por defecto. El navegador no tiene que “hidratar” toda la página, solo las islas interactivas.

Estructura de Archivos#

Para mantener el orden, utilicé una estructura modular estricta:

  • public/ Assets estáticos (fonts, favicon, humans.txt)
  • src/
    • assets/ Imágenes optimizadas y SVGs
    • components/
      • blog/ Componentes específicos del blog
      • common/ UI Global (Head, ThemeToggle, Search)
      • layout/ Estructurales (Navbar, Footer)
      • mdx/ Componentes para usar dentro de Markdown
      • seo/ Componentes para SEO (Schema, Breadcrumbs)
      • ui/ Primitivas (Button, Icon, Card)
    • content/ * MDX Collections (blog, projects, now)*
      • blog/ Contenido del blog
      • projects/ Contenido de proyectos
    • i18n/ Diccionarios y utilidades de traducción
    • layouts/ Plantillas de página (Base, Prose)
    • pages/ Rutas del sistema (File-based routing)
      • [lang] La ruta definida para i18n
        • index.astro Y muchos archivos mas
    • scripts/ Lógica cliente (main.ts)
    • styles/ CSS Global y ResetS
    • utils/ Helpers (date, slugify, ranking)
  • astro.config.mjs Configuración del compilador

2. Gestión de Imágenes (El asesino del LCP)#

El 90% de los problemas de rendimiento son imágenes mal optimizadas. No basta con comprimir; necesitas formatos modernos y dimensiones explícitas.

En lugar de usar la etiqueta <img> nativa, delegué todo el trabajo pesado al componente <Image /> de Astro, que procesa las imágenes en tiempo de build usando sharp.

Mira la diferencia en código:

src/components/Hero.astro
---
import { Image } from 'astro:assets';
import myPhoto from '../../assets/profile.jpg';
---

<img src="/profile.jpg" alt="Yo" />

<Image 
  src={myPhoto} 
  alt="Foto de perfil de ingeniería"
  width={400}
  height={400}
  format="avif"
  loading="eager" />

3. Tipografía: Adiós Google Fonts#

Cargar fuentes desde fonts.googleapis.com es un error de novato en 2024 . Añades una petición DNS, una conexión TCP y una negociación TLS extra antes de empezar a descargar el archivo.

Estrategia de “Self-Hosting”#

  1. Descargué las fuentes en formato .woff2 (la mejor compresión).
  2. Usé font-display: swap para asegurar que el texto sea visible inmediatamente, aunque la fuente no haya cargado.
  3. Pre-cargué las fuentes críticas en el <head>.
src/styles/global.css
/* src/styles/global.css */
@font-face {
  font-family: 'Manrope';
  src: url('/fonts/Manrope-variable.woff2') format('woff2');
  font-display: swap; /* 👈 Evita el texto invisible */
  font-weight: 100 900;
}

4. El dogma del “Zero-JS”#

Aquí es donde me puse radical. Decidí que mi portafolio no usaría React, Vue ni Svelte. Todo sería HTML y CSS moderno.

  • ¿Animaciones? CSS View Transitions.
  • ¿Estado global? No lo necesito.
  • ¿Interactividad compleja? Web Components nativos (Vanilla JS).
Resultado del Bundle
Ahora (Astro)
17 KB de JS total.

5. Trade-offs: La letra pequeña#

Como ingeniero senior, debo ser honesto. Llegar al 100/100 implicó sacrificios. No todo es color de rosa.

  • Transiciones entre páginas: Al no ser una SPA (Single Page Application), perdí la capacidad de hacer transiciones de estado complejas entre rutas de forma nativa (aunque las View Transitions de Astro 5 lo mitigan casi por completo).
  • DX en interacciones complejas: Escribir Vanilla JS para un carrusel o un modal es más difícil tedioso que usar un componente de React listo para usar.
  • Librerías de terceros: Tuve que rechazar librerías de UI populares porque traían dependencias pesadas.

Conclusión#

Lograr 100/100 en Lighthouse no garantiza que tu sitio sea exitoso, pero garantiza que respetas el tiempo y los datos de tus usuarios.

La ingeniería web moderna no se trata de cuántos frameworks puedes apilar, sino de cuánto puedes quitar sin romper la experiencia.

Referencias y Recursos#