De WordPress a Astro: Cómo logramos Lighthouse 100 en nuestro rediseño

Seré honesto contigo: nuestro sitio WordPress antiguo era vergonzoso. No porque se viera mal — en realidad se veía bastante bien. ¿Pero bajo el capó? Un Time to Interactive de 3,2 segundos, una puntuación de rendimiento de Lighthouse rondando los 58, y un montón de plugins que hacían que cada deploy pareciera desactivar una bomba. Somos una agencia de desarrollo web. Construimos sitios rápidos para clientes. Y nuestro propio sitio era... no rápido.

Entonces lo derribamos y lo reconstruimos con Astro. El resultado: puntuaciones perfectas de 100 en las cuatro categorías de Lighthouse — Rendimiento, Accesibilidad, Mejores Prácticas y SEO. No en una sola página. En todas las páginas. Esta es la historia de cómo llegamos allí, qué se rompió en el camino, y qué haríamos de manera diferente.

Tabla de Contenidos

De WordPress a Astro: Cómo logramos Lighthouse 100 en nuestro rediseño

Por qué dejamos WordPress

Mira, WordPress impulsa aproximadamente el 43% de la web. No es una plataforma mala. Hemos construido muchos sitios WordPress para clientes y continuaremos haciéndolo cuando sea el ajuste correcto. Pero para nuestro propio sitio de agencia — un sitio de marketing mayormente estático con un blog — WordPress era excesivo de la peor manera.

Así se veía nuestra configuración de WordPress:

  • Tema: Tema personalizado construido en Sage (Roots.io)
  • Plugins: 14 plugins activos incluyendo Yoast SEO, WP Rocket, Advanced Custom Fields Pro, Gravity Forms, y algunos otros
  • Hosting: Plan WP Engine Professional a $60/mes
  • CDN: Cloudflare Pro a $20/mes
  • Complejidad de construcción: Templating PHP, Webpack para assets, base de datos MySQL

Incluso con WP Rocket haciendo caché agresivo, nuestros Core Web Vitals eran mediocres. El Largest Contentful Paint (LCP) era de 2,4 segundos en móvil. Cumulative Layout Shift (CLS) era 0,12 — no es terrible, pero tampoco es bueno. Y cada vez que actualizábamos un plugin, había una probabilidad distinta de cero de que algo se rompiera.

¿La verdadera razón? Estábamos pagando $80/mes en costos de hosting para un sitio que recibía quizás 3.000 visitas al mes. Ese no es mucho tráfico, y ese es mucho dinero para lo que era esencialmente un sitio folleto con un blog.

El punto de quiebre

La gota que derramó el vaso llegó en enero de 2025. Una actualización del núcleo de WordPress rompió nuestros bloques Gutenberg personalizados. Arreglarlo requería actualizar ACF Pro, que requería actualizar la compatibilidad de versión PHP del tema, que requería actualizar el entorno de hosting. Lo que debería haber sido una actualización rutinaria se convirtió en un día completo de trabajo.

Miré a nuestro equipo y dije, "Les decimos a los clientes que vayan sin cabeza. ¿Por qué no estamos comiendo nuestra propia comida?"

Por qué elegimos Astro

Evaluamos cuatro opciones para la reconstrucción:

Framework Ventajas Desventajas Nuestro veredicto
Next.js Lo conocemos bien, excelente ecosistema Excesivo para un sitio de contenido, requiere servidor o runtime de borde Demasiado pesado
Astro Enfocado en contenido, envía cero JS por defecto, arquitectura de islas Ecosistema más pequeño, más nuevo Ajuste perfecto
Eleventy Simple, compilaciones rápidas, maduro Modelo de componentes limitado, menos DX moderno Segunda opción cercana
Hugo Compilaciones extremadamente rápidas, binario único Templating en Go es doloroso, flexibilidad limitada No para nosotros

Construimos muchos proyectos Next.js para clientes, y es nuestro go-to para cualquier cosa con funcionalidad dinámica. Pero para un sitio de marketing rico en contenido? Next.js envía un runtime de JavaScript sin importar si lo necesitas o no. Incluso con exportación estática, estás enviando React al navegador.

La filosofía de Astro resonó con nosotros: enviar HTML, añadir JavaScript solo donde lo necesites. Su arquitectura de islas significa que puedes tener un componente React completamente interactivo sentado junto a HTML completamente estático, y las partes estáticas envían cero JavaScript. Eso es exactamente lo que necesitábamos.

También hemos estado haciendo más trabajo de desarrollo en Astro para clientes durante 2024, así que el equipo se sentía cómodo con el framework. No era un ejercicio de aprendizaje — era una herramienta en la que ya confiábamos.

La pregunta de la capa de contenido

Una decisión que tomamos temprano: no íbamos a usar un CMS sin cabeza para nuestro propio sitio. Para proyectos de clientes, a menudo recomendamos configuraciones de CMS sin cabeza con Contentful, Sanity, o Storyblok. Pero para nuestro blog, donde cada autor es un desarrollador cómodo con Markdown y Git? Content Collections en Astro con archivos MDX comprometidos en el repositorio fue más simple y rápido.

Sin llamadas API en tiempo de construcción. Sin red de entrega de contenido para contenido. Sin servicio extra que gestionar o por el que pagar. Solo archivos en una carpeta.

La estrategia de migración

No hicimos una migración de un solo golpe. Aquí está nuestro enfoque por fases:

Fase 1: Auditoría de contenido (1 semana) Exportamos todo el contenido de WordPress usando wp-cli y convertimos posts a MDX usando un script personalizado construido con turndown (convertidor de HTML a Markdown) más limpieza de regex. Teníamos 47 posts en el blog en ese momento. Aproximadamente 12 de ellos eran obsoletos o tenían bajo rendimiento, así que redirigimos esos a contenido más nuevo relevante y no los migramos.

Fase 2: Sistema de diseño en Astro (2 semanas) Reconstruimos nuestra librería de componentes como componentes de Astro. Botones, tarjetas, layouts de sección, navegación — todo como archivos .astro. Sin framework necesario para ninguno de ellos. HTML y CSS puros con estilos limitados.

Fase 3: Construcción de páginas (2 semanas) Página de inicio, páginas de capacidades, acerca de, contacto, listado de blog, posts de blog individuales, 404. Construimos todo como páginas de Astro con nuestra librería de componentes.

Fase 4: Optimización de rendimiento (1 semana) Aquí es donde realmente sucedió el trabajo de Lighthouse 100. Más abajo sobre esto.

Fase 5: Lanzamiento y redirección (2 días) Configuramos redirecciones 301 adecuadas para cada URL antigua, verificamos con Screaming Frog que nada estuviera roto, presentamos el nuevo mapa del sitio en Google Search Console, y cambiamos DNS.

Línea de tiempo total: aproximadamente 6 semanas de trabajo a tiempo parcial junto con proyectos de clientes.

De WordPress a Astro: Cómo logramos Lighthouse 100 en nuestro rediseño - arquitectura

Decisiones de arquitectura que marcaron la diferencia

Cero JavaScript por defecto

Todo nuestro sitio se envía con aproximadamente 2KB de JavaScript en total. Eso no es una errata. Dos kilobytes. Y la mayoría de eso es un pequeño script para el toggle de navegación móvil y análisis.

Aquí está nuestro nav móvil — sin framework, sin dependencias:

---
// MobileNav.astro
---
<button id="menu-toggle" aria-expanded="false" aria-controls="mobile-menu">
  <span class="sr-only">Toggle menu</span>
  <svg><!-- hamburger icon --></svg>
</button>
<nav id="mobile-menu" hidden>
  <slot />
</nav>

<script>
  const toggle = document.getElementById('menu-toggle');
  const menu = document.getElementById('mobile-menu');
  
  toggle?.addEventListener('click', () => {
    const expanded = toggle.getAttribute('aria-expanded') === 'true';
    toggle.setAttribute('aria-expanded', String(!expanded));
    menu?.toggleAttribute('hidden');
  });
</script>

Esa etiqueta <script> en un componente de Astro se agrupa y desduplica automáticamente. Es pequeña, es vanilla JS, y funciona en todas partes.

Estrategia CSS: Estilos limitados + una capa global mínima

Usamos CSS limitado integrado de Astro para estilos a nivel de componente y una sola hoja de estilo global (aproximadamente 8KB minificada) para tipografía, reset, propiedades personalizadas, y clases de utilidad. Sin Tailwind. Toma controvertida, lo sé.

Amamos Tailwind para aplicaciones más grandes y proyectos de clientes. Pero para un sitio de este tamaño, agregó complejidad de construcción y tamaño de archivo que no necesitábamos. Nuestro CSS escrito a mano es más pequeño que lo que habría sido la salida de Tailwind, incluso con purgación.

/* Propiedades personalizadas globales */
:root {
  --color-text: #1a1a2e;
  --color-bg: #ffffff;
  --color-accent: #e94560;
  --color-accent-dark: #c81e45;
  --font-body: 'Inter', system-ui, sans-serif;
  --font-heading: 'Cal Sans', var(--font-body);
  --max-width: 72rem;
  --space-unit: 0.25rem;
}

Generación estática con precarga inteligente

Cada página se genera estáticamente en tiempo de construcción. Usamos la integración prefetch integrada de Astro para precarga de enlaces al pasar el mouse, haciendo que la navegación se sienta instantánea:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://socialanimal.dev',
  integrations: [mdx(), sitemap()],
  prefetch: {
    prefetchAll: false,
    defaultStrategy: 'hover',
  },
  build: {
    inlineStylesheets: 'auto',
  },
});

Optimizaciones de rendimiento en profundidad

Llegar a Lighthouse 100 no es solo elegir el framework correcto. Astro te da una ventaja, pero los últimos 10-15 puntos requieren esfuerzo deliberado. Aquí está lo que hicimos.

Optimización de imágenes

El componente <Image /> integrado de Astro maneja imágenes responsivas con conversión automática de formato (WebP/AVIF), carga perezosa, y atributos width/height adecuados para prevenir CLS.

---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---
<Image 
  src={heroImage} 
  alt="Equipo de desarrollo de Social Animal trabajando en arquitectura sin cabeza"
  widths={[400, 800, 1200]}
  sizes="(max-width: 600px) 400px, (max-width: 900px) 800px, 1200px"
  format="avif"
  fallbackFormat="webp"
  quality={80}
  loading="eager"
/>

Para la imagen del héroe específicamente, usamos loading="eager" ya que está por encima del pliegue. Todo lo demás obtiene loading="lazy" por defecto.

También revisamos cada imagen del sitio y nos preguntamos: "¿Esto realmente necesita ser una imagen?" Varios elementos decorativos se convirtieron en gradientes CSS o SVGs en su lugar. El fondo de nuestra sección de héroe, por ejemplo, es un gradiente CSS con una textura de ruido sutil aplicada a través de un pequeño SVG en línea.

Estrategia de carga de fuentes

Las fuentes son un asesino de Lighthouse. Aquí está nuestro enfoque:

  1. Auto-alojar todo. Sin CDN de Google Fonts. Descargamos Inter y Cal Sans y los servimos desde nuestro propio dominio. Eso elimina una búsqueda de DNS, conexión TCP, y handshake TLS a fonts.googleapis.com.

  2. Subconjunto agresivo. Usamos glyphhanger para analizar qué caracteres realmente usamos, luego subconjunto nuestras fuentes con pyftsubset. Nuestro Inter Regular WOFF2 pasó de 96KB a 18KB.

  3. Usar font-display: swap con un fallback de fuente del sistema cuidadosamente elegido que coincida con métricas de cerca, minimizando el cambio de diseño durante el swap.

  4. Precarga los archivos de fuente críticos:

<link rel="preload" href="/fonts/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/cal-sans-latin-600.woff2" as="font" type="font/woff2" crossorigin />

Hosting: Cloudflare Pages

Nos movimos de WP Engine ($60/mes) a Cloudflare Pages (tier gratuito). Sí, gratis. Nuestro sitio está bien dentro de los límites del plan gratuito de Cloudflare — 500 compilaciones por mes, ancho de banda ilimitado, solicitudes ilimitadas.

Cloudflare Pages se despliega desde un push de Git, sirve desde su red de borde global, y maneja encabezados de caché automáticamente. Los tiempos de compilación promedian 22 segundos para todo nuestro sitio. Compara eso con nuestra configuración de WordPress donde una purga de caché sola podía tomar más tiempo.

El costo mensual de hosting bajó de $80 a $0.

Línea de CSS crítica integrada

Astro integra automáticamente hojas de estilo pequeñas cuando estableces build.inlineStylesheets: 'auto'. Para nuestras páginas, cada estilo crítico está integrado en el <head>, lo que significa que hay cero solicitudes CSS que bloquean la renderización. El navegador puede comenzar a pintar inmediatamente.

Disciplina de scripts de terceros

Aquí es donde la mayoría de sitios pierden sus puntuaciones perfectas. Cada script de terceros es un desastre potencial de rendimiento. Limitamos los nuestros sin piedad:

  • Análisis: Cambiamos de Google Analytics (70KB+ de JavaScript) a Plausible Analytics (< 1KB de script, cargado async). Pagamos $9/mes por Plausible, y la calidad de datos es honestamente mejor para nuestras necesidades.
  • Formularios: Nuestro formulario de contacto en /contact usa un formulario HTML simple con manejo del lado del servidor a través de Cloudflare Pages Functions. Sin librería de formularios JavaScript.
  • Sin widgets de chat. Sin incrustaciones de redes sociales. Sin banners de consentimiento de cookies (no usamos cookies que requieran consentimiento).

La tarjeta de puntuación Lighthouse 100

Aquí están nuestras puntuaciones reales de Lighthouse a partir de mayo de 2025, medidas usando Chrome DevTools en una conexión acelerada (simulación móvil predeterminada de Lighthouse):

Métrica Puntuación
Rendimiento 100
Accesibilidad 100
Mejores prácticas 100
SEO 100
First Contentful Paint 0.6s
Largest Contentful Paint 0.8s
Total Blocking Time 0ms
Cumulative Layout Shift 0
Speed Index 0.8s

El Total Blocking Time de 0ms es mi estadística favorita. Cero. Esencialmente no hay JavaScript bloqueando el hilo principal. Nunca.

Antes y después: Los números

Métrica WordPress (Antes) Astro (Después) Mejora
Rendimiento de Lighthouse 58 100 +72%
LCP (móvil) 2.4s 0.8s 3x más rápido
CLS 0.12 0 Eliminado
TBT 380ms 0ms Eliminado
Peso de página (inicio) 1.8MB 142KB 92% más pequeño
Solicitudes HTTP 47 6 87% menos
JavaScript enviado 340KB 2KB 99.4% menos
Costo mensual de hosting $80 $9 (solo Plausible) 89% más barato
Tiempo de compilación/despliegue 3-5 min 22 seg ~10x más rápido
Time to First Byte 420ms 18ms 23x más rápido

La reducción de peso de página es asombrosa incluso para nosotros. 1.8MB a 142KB. Eso es lo que sucede cuando dejas de enviar jQuery, React, el cargador de script de WP Rocket, el inyector de marcado de esquema de Yoast, y catorce hojas de estilo de plugins.

Lo que hicimos mal en el camino

No fue todo un viaje sin problemas. Hora de honestidad.

Error 1: Casi sobre-ingenierizamos la gestión de contenido

Nuestro instinto inicial fue configurar Sanity como un CMS sin cabeza para el blog. Pasamos dos días configurando esquemas e instalando Sanity Studio antes de retroceder y preguntarnos, "¿Quién realmente va a usar esto?" La respuesta fue... nosotros. Desarrolladores. Que estamos perfectamente felices escribiendo MDX en VS Code. Arrancamos Sanity e implementamos Astro Content Collections. Ahorramos costos continuos y complejidad.

Error 2: El subconjunto de fuentes rompió caracteres especiales

Nuestro subconjunto de fuente inicial fue demasiado agresivo. Eliminamos caracteres que pensábamos que nunca usaríamos, luego publicamos un post de blog con un guión em y algunas comillas rizadas que se representaron como cajas. Lección: prueba tus subconjuntos con contenido real, no solo "ABCDEFG."

Error 3: Olvidamos sobre imágenes OpenGraph

Lanzamos sin imágenes OG dinámicas. Cuando alguien compartía un post de blog en Twitter/X o LinkedIn, mostraba un fallback genérico. Tuvimos que volver atrás e construir un pipeline de generación de imágenes OG usando @astrojs/og (que usa Satori bajo el capó). Debería haber estado en el alcance original.

Error 4: El mapa de redirección 301 tenía espacios

A pesar de usar Screaming Frog para mapear URLs antiguas, nos perdimos un puñado de URLs de imagen que sitios externos estaban hotlinking. Los atrapamos en el análisis de Cloudflare aproximadamente una semana después del lanzamiento y agregamos los redireccionamientos faltantes. Siempre verifica tus registros del servidor después de una migración — Google Search Console no lo atrapará todo.

Lecciones para tu propia migración

Si estás considerando mudar de WordPress a un framework centrado en lo estático, aquí está lo que te diría:

  1. Audita antes de migrar. Elimina contenido que no está funcionando. Una migración es una gran oportunidad para podar.

  2. Empareja la herramienta con el trabajo. Astro fue perfecto para nosotros porque somos principalmente contenido. Si necesitas interactividad pesada, Next.js o un framework similar podría ser la mejor opción.

  3. No hagas culto de carga de tu arquitectura antigua. No intentamos replicar nuestra configuración de WordPress en Astro. Repensamos todo desde cero. ¿Realmente necesitamos un plugin de formulario? No, un elemento <form> con una función sin servidor funciona bien.

  4. Mide antes, mide después, mide continuamente. Configuramos un trabajo de Lighthouse CI en GitHub Actions que se ejecuta en cada solicitud de extracción. Si una PR baja cualquier puntuación por debajo de 95, falla la verificación.

  5. Presupuesta para el "último 5%." Pasar de Lighthouse 85 a 95 es directo. Pasar de 95 a 100 requiere subconjunto de fuentes, análisis de CSS crítico, optimización de formato de imagen, y auditoría de scripts de terceros. Planifica tiempo para esto.

  6. Tus costos de hosting deberían avergonzar tu configuración antigua. Si estás sirviendo archivos estáticos y aún pagando tarifas de hosting significativas, algo está mal. El hosting estático es una mercancía ahora.

Si estás interesado en lo que sería una migración como esta para tu proyecto, consulta nuestra página de precios o ponte en contacto. Hemos hecho esta ruta de migración para varios clientes ahora, y las ganancias de rendimiento son consistentemente dramáticas.

Preguntas frecuentes

¿Cuánto tiempo lleva migrar un sitio WordPress a Astro? Para nuestro sitio (aproximadamente 50 páginas incluyendo posts de blog), tomó aproximadamente 6 semanas de trabajo a tiempo parcial. Un sitio más grande con cientos de posts y tipos de post personalizados complejos podría tomar 8-12 semanas. El desarrollo real suele ser más rápido que la auditoría de contenido y el mapeo de redirecciones.

¿Puedes obtener Lighthouse 100 con Next.js en lugar de Astro? Es posible pero significativamente más difícil. Next.js envía un runtime de JavaScript al navegador incluso para páginas estáticas (la capa de hidratación de React). Puedes acercarte — puntuaciones de 95-99 son alcanzables con optimización cuidadosa. Pero el enfoque de cero-JS-por-defecto de Astro hace que las puntuaciones perfectas sean mucho más alcanzables para sitios de contenido.

¿Qué hay de características de WordPress como formularios de contacto y búsqueda? Los formularios de contacto funcionan bien con formularios HTML puros y un backend de función sin servidor (Cloudflare Pages Functions, Netlify Functions, etc.). Para búsqueda, usamos una búsqueda del lado del cliente con Pagefind, que construye un índice de búsqueda en tiempo de construcción y envía solo 5KB de JavaScript. Es rápido y funciona sin conexión.

¿Migrar de WordPress a Astro daña el SEO? No si lo manejas correctamente. Configuramos redirecciones 301 para cada URL, mantuvimos nuestra estructura de URL donde fue posible, presentamos un nuevo mapa del sitio, y mantuvimos todos nuestros datos estructurados. Nuestro tráfico orgánico en realidad aumentó 23% en los tres meses después de la migración, probablemente debido a mejores Core Web Vitals.

¿Cómo manejas contenido dinámico como comentarios en un sitio Astro? No tenemos comentarios en nuestro blog — eran principalmente spam en WordPress de todas formas. Si necesitas comentarios, servicios como Giscus (basado en GitHub Discussions) o Hyvor Talk funcionan bien como componentes incrustados. Se cargan como islas de Astro, así que no afectan la carga inicial de la página.

¿Es Astro listo para producción para sitios grandes? Absolutamente. Astro 5.x (lanzado a finales de 2024) es maduro y estable. Empresas como Porsche, Google, Microsoft, y Netlify lo usan en producción. El rendimiento de compilación también se escala bien — sitios con miles de páginas se construyen en menos de un minuto con la configuración correcta.

¿Cómo es el mantenimiento continuado comparado con WordPress? Dramáticamente menos. Sin actualizaciones de plugins, sin mantenimiento de bases de datos, sin parches de seguridad para PHP. Actualizamos Astro y sus dependencias quizás una vez al mes a través de PRs de Dependabot. Cada actualización toma aproximadamente 5 minutos para revisar y fusionar. Compara eso con la cinta de correr de actualizaciones de WordPress.

¿Pueden los miembros del equipo no técnicos aún editar contenido en un sitio Astro? Con nuestra configuración (archivos MDX en Git), necesitas estar cómodo con Markdown y flujos de trabajo Git básicos. Para equipos con editores no técnicos, recomendamos emparejar Astro con un CMS sin cabeza como Sanity, Contentful, o Storyblok. Los editores obtienen una interfaz visual, y aún obtienes todos los beneficios de rendimiento de la generación estática.