Skip to main content
Volver al blogCopiar Markdown
·Actualizado ·9 min de lectura
·astroweb developmentjavascript

Astro 6 en 2026: ~100 en Lighthouse y una fracción del JS

Qué es Astro y por qué carga tan poco JS: Islands, la Content Layer API y la migración real de Next.js a Astro que quitó casi todo el JS de mi portfolio. →

Óscar Gallego

Óscar Gallego

Ingeniero de Software

Astro 6 framework: ilustración de cohete con concepto de cero JavaScript
En este artículo

Actualizado mayo 2026: ahora cubre Astro 6. Este post lo escribí originalmente para Astro 5 a finales de 2025. Desde entonces actualicé este sitio a Astro 6 (estable desde marzo de 2026), y la propuesta sigue intacta: cero JS por defecto, Islands, y unos Core Web Vitals que de verdad puedes aprobar. La Content Layer API y las directivas client:* que ves abajo son idénticas en v6. Las diferencias están más bajo el capó: Node mínimo ^22.12.0 || ^24.0.0, Zod v4, y los periodos de gracia de v5 ya cerrados. Si lo que quieres es la guía de actualización desde Astro 5 en lugar de una intro, mira mi guía de migración a Astro 6, y para el siguiente salto, la migración a Astro 7.

Mi portfolio enviaba un bundle pesado de JavaScript para renderizar lo que es, sobre todo, texto. Con Astro envía una fracción de eso, y en este sitio ahora rondo los 100 en Lighthouse.

El mismo contenido. El mismo diseño. Este post es el porqué y el cómo.

Qué es Astro y por qué importa la versión 6

Astro es un framework web moderno diseñado para construir sitios rápidos y centrados en el contenido: blogs, portfolios, webs de marketing. Su principal característica es la arquitectura de “cero JavaScript por defecto”, que envía solo HTML y CSS al navegador y carga JavaScript únicamente para los componentes interactivos que lo necesitan.

Las principales novedades de Astro 5 (todas heredadas por la 6) se centran en rendimiento y flexibilidad:

  • Content Layer API: unifica la carga de contenido desde múltiples fuentes (archivos locales, CMS headless) con validación de datos y type-safety en tiempo de build gracias a su sistema de loaders.
  • Islands Architecture mejorada: permite una hidratación de componentes más granular con directivas como client:visible, lo que reduce drásticamente la cantidad de JavaScript enviado al cliente.
  • Builds más rápidos: el nuevo sistema de caché y el procesamiento en paralelo recortan los tiempos de build, sobre todo en rebuilds incrementales.
  • Optimización de assets integrada: el componente <Image /> ahora maneja la optimización de imágenes, generando múltiples tamaños y formatos automáticamente.

Por qué migré mi portfolio a Astro 5

Después de probar Next.js, Gatsby y otros frameworks, Astro 5 me convenció por su enfoque radical: cero JavaScript por defecto. No como eslogan de marketing, como arquitectura real.

El problema que resuelve Astro

La mayoría de frameworks modernos envían todo el código JavaScript al navegador, incluso para contenido estático. El resultado:

  • Bundles de 200-400KB para páginas simples
  • Time to Interactive (TTI) de 3-5 segundos en móviles
  • JavaScript execution time que bloquea el thread principal

Astro invierte el paradigma: HTML primero, JavaScript solo cuando es necesario.

Content Layer API: el cambio que justifica el número de versión

La mayor innovación de Astro 5 es el Content Layer API. Antes, las Content Collections solo soportaban archivos locales. Ahora puedes cargar contenido desde cualquier fuente.

Ejemplo práctico: blog con CMS headless

import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';

// Contenido local (Markdown)
const blog = defineCollection({
  loader: glob({
    pattern: "**/*.{md,mdx}",
    base: "./src/content/blog"
  }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    author: z.string().default("Tu Nombre"),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
  }),
});

export const collections = { blog };

Lo que te compra el nuevo sistema de loaders

1. Type-safety real

Antes, TypeScript confiaba en que tus archivos siguieran el schema. Confiaba. Ahora, con Zod validation:

// FALLA: esto revienta en BUILD TIME, no en runtime
---
title: 123  # Error: Expected string, received number
pubDate: "fecha-invalida"  # Error: Invalid date
---

2. Performance en builds

En mi portfolio (20 páginas), el build se volvió bastante más rápido. ¿Por qué?

  • Caché inteligente: solo recompila archivos modificados
  • Parallel processing: procesa múltiples fuentes simultáneamente
  • Tree-shaking optimizado: elimina código no usado de validaciones Zod

3. Flexibilidad sin límites

Puedes combinar múltiples fuentes:

// Futuro: Cargar desde API externa
import { strapiLoader } from '@astrojs/strapi-loader';

const externalBlog = defineCollection({
  loader: strapiLoader({
    url: 'https://api.ejemplo.com',
    collection: 'posts'
  }),
  schema: z.object({...}),
});

Islands: hidrata el botón, no la página

Este es el concepto que diferencia Astro de otros frameworks.

El problema tradicional

Con Next.js o Nuxt, si tienes un botón interactivo, toda la página se hidrata:

// Next.js: Envía TODO el bundle al navegador
export default function Page() {
  return (
    <div>
      <Header /> {/* Estático, pero se hidrata */}
      <Article /> {/* Estático, pero se hidrata */}
      <InteractiveButton /> {/* Necesita hidratación */}
      <Footer /> {/* Estático, pero se hidrata */}
    </div>
  );
}

La versión Astro

---
import Header from './Header.astro';
import Article from './Article.astro';
import InteractiveButton from './InteractiveButton.svelte';
import Footer from './Footer.astro';
---

<Header />
<Article />
<!-- Solo este componente se hidrata -->
<InteractiveButton client:visible />
<Footer />

Resultado real: mi homepage pasó de un bundle de cliente entero (Next.js) a apenas el JS del botón dark mode.

Directivas de hidratación: cuándo usar cada una

DirectivaUso idealJS Bundle
client:loadComponentes críticos above-the-foldSe carga inmediatamente
client:idleWidgets no críticosEspera a requestIdleCallback
client:visibleComponentes below-the-foldSe carga al entrar en viewport
client:mediaComponentes responsivosCondicional por media query
client:onlySPA embebidosSolo en navegador

Ejemplo real: galería de imágenes

---
import ImageGallery from '@components/ImageGallery.react';
---

<!-- Solo carga cuando el usuario hace scroll hasta aquí -->
<ImageGallery
  client:visible
  images={galleryImages}
/>

Migración desde otro framework

Desde Next.js

Los retos con los que te vas a encontrar de verdad:

  1. API Routes: Astro no tiene /pages/api. Usa endpoints:
// src/pages/api/newsletter.ts
export async function POST({ request }) {
  const data = await request.json();
  // Tu lógica aquí
  return new Response(JSON.stringify({ success: true }), {
    headers: { 'Content-Type': 'application/json' }
  });
}
  1. Dynamic routes: Cambia [id].js a [id].astro, usa getStaticPaths:
---
export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map(post => ({
    params: { id: post.id },
    props: { post }
  }));
}
---
  1. Data fetching: No hay getServerSideProps. En Astro todo se ejecuta en build time:
---
// Esto se ejecuta en el servidor durante el build
const response = await fetch('https://api.example.com/data');
const data = await response.json();
---

<div>{data.title}</div>

Mi portfolio, antes y después

Son mis propios números en este sitio concreto, no un benchmark que debas esperar reproducir:

Antes (Next.js 14): un Time to Interactive de varios segundos en móvil, un bundle gzipped considerable y bastante Total Blocking Time en el hilo principal.

Después (Astro 5): el First Contentful Paint bajó a una fracción, el Total Blocking Time prácticamente desapareció y el bundle se quedó en poco más que el toggle de dark mode.

En este sitio eso me dejó alrededor de 100 en Lighthouse en las distintas categorías. Lo tuyo variará según tu contenido y tus componentes.

Dónde gana Astro, y dónde te va a pelear

La versión honesta del pitch: Astro está construido para contenido. Sal de ahí y nadarás contracorriente.

Donde brilla:

  • Blogs y portfolios
  • Sitios de marketing
  • Documentación técnica
  • E-commerce con catálogos estáticos
  • Landing pages de alto rendimiento

Donde yo no lo usaría:

  • Dashboards con actualización en tiempo real
  • SPAs con mucho estado compartido
  • Apps que requieren SSR dinámico (usa Astro con SSR adapter)
  • Aplicaciones tipo Gmail o Figma

Si tu app vive en la segunda lista, elegir Astro por la nota de Lighthouse es elegir la herramienta equivocada por una buena razón. No lo hagas.

Trucos de producción

1. Optimización de imágenes

---
import { Image } from 'astro:assets';
import heroImage from '@assets/hero.jpg';
---

<!-- Genera múltiples tamaños automáticamente -->
<Image
  src={heroImage}
  alt="Hero"
  widths={[400, 800, 1200]}
  sizes="(max-width: 800px) 100vw, 800px"
  loading="eager"
/>

2. Prefetching para navegación instantánea

<script>
  // Prefetch al hacer hover en links
  document.querySelectorAll('a[href^="/"]').forEach(link => {
    link.addEventListener('mouseenter', () => {
      const href = link.getAttribute('href');
      const prefetchLink = document.createElement('link');
      prefetchLink.rel = 'prefetch';
      prefetchLink.href = href;
      document.head.appendChild(prefetchLink);
    });
  });
</script>

3. Dark mode sin FOUC (Flash of Unstyled Content)

<script is:inline>
  // Ejecuta antes del render para evitar flash
  const theme = localStorage.getItem('theme') || 'light';
  document.documentElement.classList.add(theme);
</script>

Seis meses en producción

Astro no es “otro framework más”. Es una apuesta radical por el rendimiento sin sacrificar DX, y después de 6 meses en producción la apuesta ha pagado:

  • Deployments más rápidos: builds claramente más cortos, sobre todo los incrementales
  • Costes reducidos: CDN edge hosting a $0/mes (Vercel free tier)
  • SEO mejorado: Core Web Vitals cómodamente en verde en este sitio
  • Menor complejidad: sin hydration bugs, sin bundle size anxiety

La capa de estilos sigue la misma filosofía: combino Astro con Tailwind CSS 4, cuyo motor en Rust hace rebuilds en microsegundos, para que el pipeline de CSS quede tan ligero como el de JS.

Si estás construyendo un sitio content-heavy, abre tu bundle analyzer y mira cuántos kilobytes de JavaScript envías para renderizar texto. Luego decide.

Lectura relacionada: ¿ya estás en Astro 5 y mirando el salto? Mi guía de migración a Astro 6 cubre los cambios del Content Layer, el lío de Zod v4 y las APIs que no sobrevivieron.

Fuentes


P.D. ¿Migraste a Astro, o decidiste que no? Quiero ver los números del antes y el después en cualquiera de los dos casos. Escríbeme en Twitter/X.

Última actualización:

Comparte este artículo

Artículos relacionados