astro-imagenes-optimizacion

Optimización de imágenes en Astro

  • 5 min

En el desarrollo web moderno, gestionar imágenes es más complejo de lo que parece. No basta con poner una etiqueta <img>.

Debes convertir a formatos modernos (WebP/AVIF), generar diferentes tamaños para móviles y escritorios (srcset), y reservar el espacio para evitar saltos de contenido (CLS).

Hacer esto a mano es,… voy a decir tedioso (por mantener la elegancia). Afortunadamente, Astro lo hace por nosotros.

Pero antes de ver el componente para ello, debemos resolver la duda existencial de todo desarrollador de Astro: ¿Dónde guardo mis archivos?

¿Carpeta /public o /src/assets?

En la estructura de tu proyecto verás dos lugares donde parece lógico guardar imágenes. Entender la diferencia es muy importante.

La carpeta /public

Es como un “cajón de sastre”. Los archivos que pones aquí Astro no los toca. Se copian tal cual a la raíz de tu sitio web final.

  • Ruta de acceso: Se accede a ellos mediante una ruta URL absoluta (/mi-imagen.png).
  • Procesamiento: Nulo. Si la imagen pesa 5MB, el usuario descargará 5MB.
  • Caché: No tienen hash en el nombre, por lo que si cambias la imagen pero mantienes el nombre, los usuarios podrían seguir viendo la versión antigua en caché.
  • Para el favicon.ico, robots.txt o sitemap.xml.
  • Para imágenes que no quieres que se procesen (ej: gráficos vectoriales complejos o SVGs interactivos).
  • Imágenes usadas en los archivos Markdown estándar (aunque esto está cambiando).

La carpeta /src/assets

Aquí es donde ocurre la magia. Los archivos que viven dentro de src (generalmente en src/assets) son procesados por Astro (y Vite).

  • Ruta de acceso: Se deben importar en el código JavaScript/Astro como si fueran módulos.
  • Procesamiento: Astro puede analizarlas, optimizarlas y cambiarles el tamaño.
  • Caché: Al compilar, Astro renombra el archivo con un hash único (ej: logo.a4b3c.png), garantizando que el usuario siempre descargue la última versión.

Intenta guardar todas tus imágenes en src/assets. Usa public solo como último recurso.

El componente <Image />

Para aprovechar la optimización automática, Astro nos proporciona el componente <Image />. Este componente sustituye a la etiqueta HTML <img> estándar.

Para usarlo, lo importamos desde el paquete astro:assets (incluido en el core).

Uso con imágenes locales

Supongamos que tenemos una foto en src/assets/mi-foto.jpg.

---
// Importamos el componente
import { Image } from 'astro:assets';

// Importamos la imagen como si fuera un módulo de JS
import miFoto from '../assets/mi-foto.jpg';
---

<Image 
  src={miFoto} 
  alt="Una descripción accesible de la foto" 
  width={800}
/>
Copied!

Al compilar, esto no generará una etiqueta <img> normal apuntando al JPG original. Astro hará lo siguiente:

  1. Conversión de formato: Convertirá la imagen automáticamente a WebP (o AVIF), que pesa mucho menos manteniendo la calidad.
  2. Dimensiones: Detectará el alto y ancho original para añadirlos al HTML y evitar el Cumulative Layout Shift (que la página “baile” al cargar la imagen).
  3. Lazy Loading: Añadirá loading="lazy" y decoding="async" por defecto.

El HTML resultante en el navegador será algo así:

<img
  src="/_astro/mi-foto.hash123.webp"
  width="800"
  height="600"
  loading="lazy"
  decoding="async"
  alt="Una descripción accesible de la foto"
/>
Copied!

El componente <Picture />

El componente <Image /> cubre el 90% de los casos. Pero a veces necesitamos “Dirección de Arte”: mostrar una imagen recortada cuadrada en el móvil y una panorámica ancha en el escritorio.

Para eso existe el componente <Picture />, que genera una etiqueta HTML <picture> con múltiples fuentes (<source>).

---
import { Picture } from 'astro:assets';
import miImagen from '../assets/paisaje.jpg';
---

<Picture 
  src={miImagen} 
  formats={['avif', 'webp']} 
  widths={[240, 540, 720, miImagen.width]}
  sizes={`(max-width: 360px) 240px, (max-width: 720px) 540px, (max-width: 1600px) 720px, ${miImagen.width}px`}
  alt="Un paisaje increíble" 
/>
Copied!

Esto generará múltiples versiones de la imagen en distintos formatos y tamaños, y el navegador elegirá la más óptima según el ancho de pantalla y la compatibilidad del navegador.

  • Usa <Image /> por defecto. Es más simple y cubre la optimización estándar.
  • Usa <Picture /> solo si necesitas cambiar la relación de aspecto o la fuente de la imagen según el tamaño de pantalla.

Imágenes en Markdown

Si estás escribiendo un blog en Markdown, te alegrará saber que Astro también puede optimizar esas imágenes.

Si colocas tus imágenes en src/assets y usas rutas relativas en tu Markdown:

![Mi robot](../assets/robot.png)
Copied!

Astro (a través de su integración de Markdown) detectará esa referencia, procesará la imagen igual que el componente <Image /> y generará la etiqueta optimizada.