Skip to content
ImageOptimizer
ImageOptimizer
Конвертация изображений в WebP/AVIF, responsive srcset, очередь и авто-inject picture на витрине MODX 3
  1. Компоненты
  2. ImageOptimizer
  3. Интеграция на сайте

Авто-inject и picture

При imageoptimizer_inject_frontend=1 плагин на OnWebPagePrerender парсит HTML и для подходящих <img>:

  1. Находит media source и путь к файлу на диске
  2. Проверяет готовые варианты (статус done в очереди)
  3. Оборачивает в <picture> с <source type="image/webp"> / AVIF и fallback <img>
  4. Добавляет srcset, sizes, при необходимости loading и decoding

Inject не выполняется в контексте mgr, для AJAX (X-Requested-With) и для non-HTML content types.

Пример результата

Исходник:

html
<img src="assets/images/hero.jpg" alt="Hero">

После обработки (варианты 480/768/1024 и full WebP на диске):

html
<picture>
  <source type="image/webp"
    srcset="assets/images/hero.480.webp 480w,
            assets/images/hero.768.webp 768w,
            assets/images/hero.1024.webp 1024w,
            assets/images/hero.jpg.webp 1920w"
    sizes="(min-width: 1280px) 50vw, 100vw">
  <img src="assets/images/hero.jpg" alt="Hero"
    loading="lazy" decoding="async"
    srcset="..." sizes="...">
</picture>

Точная разметка зависит от imageoptimizer_breakpoints, imageoptimizer_formats и imageoptimizer_variant_pattern.

Парсер HTML и безопасность разметки

Инъекция использует html_parser.php (DOMDocument).

Полная HTML-страница

Если ответ содержит <!DOCTYPE html> или корневой <html>, inject сохраняет <html>, <head>, <body>. Страница не оборачивается в лишний контейнер.

Блоки script / style / noscript / textarea

Содержимое этих тегов временно вырезается до парсинга DOM и восстанавливается после. Строки с HTML внутри JavaScript (например innerHTML = '<div>…') не ломают страницу.

UTF-8 и кириллица

Текст в UTF-8 остаётся как есть. saveHTML() не превращает кириллицу в &#1044;. Числовые HTML-сущности в допустимом диапазоне декодируются обратно в символы.

Артефакт <!--?xml encoding="UTF-8"--> после loadHTML удаляется.

При смене формата сериализации сбрасывается HTML-кэш через константу IMAGEOPTIMIZER_HTML_SERIALIZE_REV (ключ кэша включает её значение). Актуальное значение в 1.0.4: 4.

Условия пропуска

УсловиеНастройка / атрибут
Компонент выключенimageoptimizer_enabled=0
Inject выключенimageoptimizer_inject_frontend=0
Уже внутри <picture>imageoptimizer_respect_existing_picture=1
Уже есть srcsetimageoptimizer_respect_existing_srcset=1 (только lazy/decoding)
CSS-классimageoptimizer_skip_classes (по умолчанию lazy, swiper-lazy, no-optim)
Подстрока в URLimageoptimizer_skip_src_pattern (по умолчанию thumb3x)
Явный skipdata-imageoptimizer-skip на <img>
Внешний URLне резолвится в локальный media source
Нет вариантов на дискеочередь не обработана или skip при конвертации
HTML слишком большойimageoptimizer_max_html_size (1 МБ по умолчанию)

URL с thumb3x пропускаются, чтобы не дублировать on-the-fly thumbs Thumb3x. См. Совместимость.

Lazy loading и LCP

На обработанных img по умолчанию добавляются loading="lazy" и decoding="async", если:

  • imageoptimizer_respect_existing_loading=0 или атрибут loading ещё не задан
  • img не входит в первые N на странице (imageoptimizer_skip_lazy_first_images)

Для LCP-изображения (первый экран):

html
<img src="assets/hero.jpg" alt="" data-imageoptimizer-fetchpriority="high">

Или задайте imageoptimizer_skip_lazy_first_images=1 (или больше).

Атрибут sizes

Приоритет:

  1. Атрибут sizes на <img>
  2. data-imageoptimizer-sizes
  3. imageoptimizer_default_sizes

Для карточки товара:

(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw

Кэш HTML

При imageoptimizer_html_cache=1 результат inject сохраняется в core/cache/imageoptimizer/html/.

Когда кэш не используется

  • imageoptimizer_html_cache=0
  • пользователь авторизован на фронтенде (контекст web)
  • placeholder imageoptimizer.skip_html_cache установлен (сниппеты, плагины)

Ключ кэша

Файл кэша привязан к:

  • контексту и URI ресурса
  • editedon ресурса
  • хэшу настроек inject
  • generation-счётчику (увеличивается при каждом успешном done в очереди)
  • хэшу содержимого HTML (Fenom file: и динамические include без смены editedon)
  • IMAGEOPTIMIZER_HTML_SERIALIZE_REV

Новые WebP попадают на фронт без правки ресурса в MODX.

Сброс:

  • Управление → Очистить кэш MODX
  • События OnSiteRefresh / OnCacheUpdate
  • Очистить варианты в админке (connector queue/clear)
  • Смена настроек inject или bump IMAGEOPTIMIZER_HTML_SERIALIZE_REV в коде

Если после конвертации <picture> не появился, очистите кэш MODX и HTML-кэш ImageOptimizer.

Отключить кэш для одной страницы

В сниппете или плагине до prerender:

php
$modx->setPlaceholder('imageoptimizer.skip_html_cache', true);

Ручной вывод в шаблонах

Варианты лежат рядом с оригиналом в media source:

ТипПример пути
Full WebPimage.jpg.webp
Width 768 WebPimage.768.webp
AVIFimage.768.avif

Шаблон имени: imageoptimizer_variant_pattern (плейсхолдеры {basename}, {width}, {ext}).

modx
<picture>
  <source type="image/webp"
    srcset="[[++assets_url]]images/photo.480.webp 480w,
            [[++assets_url]]images/photo.768.webp 768w,
            [[++assets_url]]images/photo.jpg.webp 1200w"
    sizes="(max-width: 768px) 100vw, 50vw">
  <img src="[[++assets_url]]images/photo.jpg" alt="..." width="1200" height="800">
</picture>
fenom
<picture>
  <source type="image/webp"
    srcset="{$_modx->config.assets_url}images/photo.480.webp 480w,
            {$_modx->config.assets_url}images/photo.768.webp 768w,
            {$_modx->config.assets_url}images/photo.jpg.webp 1200w"
    sizes="(max-width: 768px) 100vw, 50vw">
  <img src="{$_modx->config.assets_url}images/photo.jpg" alt="..." width="1200" height="800">
</picture>

Отключите авто-inject для таких блоков: data-imageoptimizer-skip или класс из imageoptimizer_skip_classes.

MiniShop3 и произвольные чанки

При включённом inject достаточно обычного <img src="assets/..."> в чанке товара. Плагин обрабатывает итоговый HTML страницы. Чанки MS3 править не нужно.

Связанные разделы