Оптимизация изображений

Положите полноразмерное изображение в src/ или public/, направьте на него <img> — и sitelo уменьшит его, переведёт в современный формат и перепишет тег с srcset. Ничего импортировать не нужно, никакого компонента изучать не придётся.

Включение

export default {
  images: true,
}

Кодированием занимается sharp — необязательная peer-зависимость; установите её вместе с sitelo, когда включаете изображения:

npm install -D sharp

Сайтам без оптимизации изображений устанавливать её не нужно вовсе.

Пишите обычный <img>

import { html, body, img } from 'javascript-to-html'

export default () =>
  html({ lang: 'ru' },
    body(
      img({ src: '/images/hero.png', alt: 'Рассвет над гаванью' }),
    ),
  )

Исходник 3000×2000 выходит вот таким:

<img src="/assets/img/hero.a1b2c3d4-1200.webp"
     alt="Рассвет над гаванью"
     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">

Что вы получаете

Переписывание идёт по собранному HTML, поэтому охватывает изображения и из src/, и из public/.

Параметры

export default {
  images: {
    widths: [400, 800, 1200],
    formats: ['avif', 'webp'],
    quality: { avif: 55, webp: 78, jpeg: 82 },
    exclude: ['**/og/**'],
  },
}

Два формата дают

AVIF меньше, но моложе WebP, поэтому указание обоих позволяет браузеру выбрать и сохраняет запасной вариант для старых браузеров:

<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>

Как исключить изображение

Теги, у которых уже есть srcset, которые находятся внутри <picture> или указывают на SVG, анимированный GIF либо внешний URL, остаются нетронутыми. Для всего остального скажите об этом явно:

<img src="/images/exact.png" alt="Пиксель-арт" data-no-optimize>

Изображения для соцсетей и фавиконки живут в <meta> и <link>, которые здесь никогда не переписываются — их URL остаётся неизменным.

Внешние изображения

Контент, импортированный из CMS, часто указывает на чужой сервер. Включите remote — и такие изображения будут скачаны, оптимизированы и отданы с вашего домена:

export default {
  images: {
    remote: true,
    prune: true,
  },
}

Неудачная загрузка оставляет тег ровно таким, каким он был, с предупреждением — нестабильный источник никогда не обрушит вашу сборку. Затем prune убирает локальные оригиналы, на которые больше ничего не ссылается.