nuckty
EN
Все разделы →

Изображения

Растровые изображения доступны по логическому адресу; сервер выбирает доступный формат по Accept. Сборка копирует оригинал и подготовленные варианты. Обоснование — в решении о хостинге.

Что кладёт движок

Для каждого исходного изображения движок раскладывает подготовленные варианты по каталогам форматов. Имя файла — content-hash, без исходного имени:

site/
  avif/9f8e7d6.avif      ← подготовленный вариант AVIF
  webp/9f8e7d6.webp      ← подготовленный вариант WebP
  png/9f8e7d6.png        ← оригинал, запасной вариант

Хеш учитывает расширение и байты оригинала и доступных вариантов AVIF/WebP. Изменение любого представления меняет URL. В примерах хеш сокращён; реальная длина — 16 шестнадцатеричных символов. О кэшировании — ассеты.

Один адрес в HTML

В разметке ссылка одна — логический адрес вида /_i<hash>:

<img class=article__image src=/_i9f8e7d6 alt="Шина">

Сервер отдаёт первый существующий формат по порядку: AVIF, затем WebP, затем оригинал:

location ~ ^/_i([a-f0-9]+)$ {
    set $hash $1;
    try_files $avif_dir/$hash.avif $webp_dir/$hash.webp /png/$hash.png /jpg/$hash.jpg /jpg/$hash.jpeg /svg/$hash.svg /$hash.gif /$hash.ico /webp/$hash.webp =404;
}

Оба сервера учитывают Accept: AVIF и WebP выбираются при явном разрешении формата с ненулевым q. В nginx это определяет значения $avif_dir и $webp_dir; в Apache — условия перезаписи. Затем сервер ищет оригинал. Если единственный оригинал — WebP, он доступен и без Accept. Ответы содержат Vary: Accept.

image-mapping.json

Чтобы Markdown и CSS ссылались на изображения согласованно, движок строит общий файл соответствий .build/image-mapping.json:

{
    "free/light.png": "_i62e5723492d14dc0"
}

Значение хранится без ведущего / — механизм разрешения ссылок добавляет его при чтении. Мост Markdown переписывает пути в ![](...) по этому файлу. Стадия CSS переписывает url(...) по нему же. В итоге хэшированные имена в HTML и в CSS согласованы, а формат сервер выбирает по одному адресу.

Точное совпадение нормализованного пути с ключом имеет приоритет. Markdown также проверяет путь относительно текущего исходного файла, прежде чем искать изображение только по имени. Поиск по имени допустим, если оно указывает на одно изображение; неоднозначность прерывает сборку. Более поздний уровень изображений переопределяет тот же путь относительно уровня.

Отложенная загрузка

Галерея не добавляет loading=lazy первому изображению каждой галереи, а остальным добавляет. Это не определение первого изображения страницы или первого экрана. Другие блоки задают собственную политику загрузки.

Растровые и векторные

Конвейер сканирует PNG, JPEG, GIF, WebP и SVG. Он копирует доступные AVIF/WebP рядом с растровым оригиналом; команда конвертации создаёт их для PNG/JPEG. SVG не кодируется: файл хранится как svg/<hash>.svg, а подходящая ссылка CSS встраивается как URI data:. ICO и отдельные исходники AVIF не сканируются.

Зачем так

При использовании <picture> с вложенными <source> форматы перечисляются в разметке каждого изображения. В nuckty выбор формата задаётся общими правилами сервера; преимущества и ограничения описаны в решении о хостинге.

Формат выбирает сервер. Поддержка нового кодека может потребовать изменений сбора изображений, конвертера и генератора конфигурации; одного изменения правил раздачи недостаточно.