Оптимизация изображений
На этой странице
Положите полноразмерное изображение в src/ или public/, направьте на него <img> — и sitelo уменьшит его, переведёт в современный формат и перепишет тег с srcset. Ничего импортировать не нужно, никакого компонента изучать не придётся.
Включение
export default {
images: true,
}Кодированием занимается sharp — необязательная peer-зависимость; установите её вместе с sitelo, когда включаете изображения:
npm install -D sharpСайтам без оптимизации изображений устанавливать её не нужно вовсе.
Пишите обычный <img>
export default () => `
<html lang="ru">
<body>
<img src="/images/hero.png" alt="Рассвет над гаванью">
</body>
</html>
`import { html, body, img } from 'javascript-to-html'
export default () =>
html({ lang: 'ru' },
body(
img({ src: '/images/hero.png', alt: 'Рассвет над гаванью' }),
),
)export default function Home() {
return (
<html lang="ru">
<body>
<img src="/images/hero.png" alt="Рассвет над гаванью" />
</body>
</html>
)
}Исходник 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">Что вы получаете
- Масштабирование, которое никогда не увеличивает — исходник в 600px с
widths: [400, 800, 1200]даст 400 и 600, и на этом остановится. - Современные форматы — один формат даёт обычный
<img srcset>; два и больше оборачиваются в<picture>с запасным вариантом в исходном формате. - Без скачков вёрстки —
widthиheightзаполняются из настоящего изображения, плюсloading="lazy"иdecoding="async". - Та же разметка в разработке —
sitelo(dev) переписывает страницы и отдаёт варианты по запросу, так что вы видите именно то, что опубликуете. - Общий кэш — варианты хранятся по хэшу содержимого в
node_modules/.sitelo/images, поэтому ни разработка, ни повторные сборки не кодируют одно и то же изображение дважды.
Переписывание идёт по собранному HTML, поэтому охватывает изображения и из src/, и из public/.
Параметры
export default {
images: {
widths: [400, 800, 1200],
formats: ['avif', 'webp'],
quality: { avif: 55, webp: 78, jpeg: 82 },
exclude: ['**/og/**'],
},
}widths— по умолчанию[400, 800, 1200]; наибольшее значение служит и верхней границейformats— по умолчанию['webp'];avif,webp,jpeg,pngquality— по умолчанию{ avif: 55, webp: 78, jpeg: 82 }; качество кодировщика по форматам (png использует сжатие, а не качество)sizes— атрибутsizes;sizes, указанный в теге, всегда важнееdimensions— по умолчаниюtrue; добавляетwidth/heightlazy— по умолчаниюtrue; добавляетloadingиdecodingexclude— glob-шаблоны или регулярные выражения URL изображений, которые не трогатьassetsDir— по умолчанию'assets/img'cacheDir— по умолчанию'node_modules/.sitelo/images'remote— по умолчаниюfalse; оптимизирует изображенияhttps://во время сборкиprune— по умолчаниюfalse; удаляет оригиналы, на которые больше ничего не ссылаетсяdev— по умолчаниюtrue; поставьтеfalse, чтобы в разработке отдавать нетронутые оригиналыconcurrency— параллельные кодирования, по умолчанию CPU − 1 (максимум 8); 1, если включён remote
Два формата дают
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 убирает локальные оригиналы, на которые больше ничего не ссылается.