Optimización de imágenes
En esta página
Deja una imagen a tamaño completo en src/ o public/, apunta un <img> hacia ella, y sitelo la redimensiona, la convierte a un formato moderno y reescribe la etiqueta con un srcset. Nada que importar, ningún componente que aprender.
Activarlo
export default {
images: true,
}La codificación la hace sharp, una dependencia peer opcional: instálala junto a sitelo cuando actives las imágenes:
npm install -D sharpLos sitios que no optimizan imágenes no necesitan instalarla nunca.
Escribe un <img> normal
export default () => `
<html lang="es">
<body>
<img src="/images/hero.png" alt="Amanecer sobre el puerto">
</body>
</html>
`import { html, body, img } from 'javascript-to-html'
export default () =>
html({ lang: 'es' },
body(
img({ src: '/images/hero.png', alt: 'Amanecer sobre el puerto' }),
),
)export default function Home() {
return (
<html lang="es">
<body>
<img src="/images/hero.png" alt="Amanecer sobre el puerto" />
</body>
</html>
)
}Una imagen original de 3000×2000 sale así por el otro lado:
<img src="/assets/img/hero.a1b2c3d4-1200.webp"
alt="Amanecer sobre el puerto"
sizes="(max-width: 1200px) 100vw, 1200px"
width="1200" height="800"
loading="lazy" decoding="async"
srcset="/assets/img/hero.9f8e7d6c-400.webp 400w,
/assets/img/hero.5b4a3c2d-800.webp 800w,
/assets/img/hero.a1b2c3d4-1200.webp 1200w">Qué obtienes
- Redimensionado que nunca amplía — un original de 600px con
widths: [400, 800, 1200]emite 400 y 600, y ahí se detiene. - Formatos modernos — con un solo formato obtienes un
<img srcset>normal; con dos o más se envuelve en un<picture>con una alternativa en el formato original. - Sin saltos de maquetación —
widthyheightse rellenan a partir de la imagen real, además deloading="lazy"ydecoding="async". - El mismo marcado en desarrollo —
sitelo(dev) reescribe las páginas y sirve las variantes bajo demanda, así que previsualizas lo que vas a publicar. - Una caché compartida — las variantes se indexan por hash de contenido en
node_modules/.sitelo/images, de modo que ni el desarrollo ni las recompilaciones codifican dos veces la misma imagen.
La reescritura se ejecuta sobre el HTML ya compilado, así que cubre por igual las imágenes de src/ y de public/.
Opciones
export default {
images: {
widths: [400, 800, 1200],
formats: ['avif', 'webp'],
quality: { avif: 55, webp: 78, jpeg: 82 },
exclude: ['**/og/**'],
},
}widths— por defecto[400, 800, 1200]; el mayor es también el máximoformats— por defecto['webp'];avif,webp,jpeg,pngquality— por defecto{ avif: 55, webp: 78, jpeg: 82 }; calidad del codificador por formato (png usa compresión, no calidad)sizes— el atributosizes; unsizespuesto en la etiqueta siempre ganadimensions— por defectotrue; añadewidth/heightlazy— por defectotrue; añadeloadingydecodingexclude— glob(s) o RegExp(s) de URLs de imagen que no hay que tocarassetsDir— por defecto'assets/img'cacheDir— por defecto'node_modules/.sitelo/images'remote— por defectofalse; optimiza imágeneshttps://en tiempo de compilaciónprune— por defectofalse; borra los originales que ya no referencia nadiedev— por defectotrue; ponlo afalsepara servir los originales sin tocar en desarrolloconcurrency— codificaciones en paralelo, por defecto CPUs − 1 (máx. 8); 1 cuando remote está activo
Dos formatos te dan
AVIF es más pequeño pero más reciente que WebP, así que listar ambos deja que el navegador elija y mantiene una alternativa para los antiguos:
<picture>
<source type="image/avif" srcset="/assets/img/hero.*-400.avif 400w, ..." sizes="...">
<source type="image/webp" srcset="/assets/img/hero.*-400.webp 400w, ..." sizes="...">
<img src="/assets/img/hero.*-1200.png" alt="..." srcset="..." width="1200" height="800">
</picture>Cómo excluir imágenes
Las etiquetas que ya tienen un srcset, que están dentro de un <picture>, o que apuntan a un SVG, un GIF animado o una URL remota se dejan intactas. Para cualquier otra, dilo explícitamente:
<img src="/images/exact.png" alt="Pixel art" data-no-optimize>Las imágenes de tarjetas sociales y favicons viven en <meta> y <link>, que esto nunca reescribe: conservan su URL fija.
Imágenes remotas
El contenido importado de un CMS suele apuntar al servidor de otra persona. Activa remote y esas imágenes se descargan, se optimizan y se sirven desde tu propio dominio:
export default {
images: {
remote: true,
prune: true,
},
}Una descarga que falla deja la etiqueta exactamente como estaba, con un aviso: un origen inestable nunca hace fallar tu compilación. Después, prune elimina los originales locales que ya no referencia nadie.