
Авто-inject и picture
При imageoptimizer_inject_frontend=1 плагин на OnWebPagePrerender парсит HTML и для подходящих <img>:
- Находит media source и путь к файлу на диске
- Проверяет готовые варианты (статус
doneв очереди) - Оборачивает в
<picture>с<source type="image/webp">/ AVIF и fallback<img> - Добавляет
srcset,sizes, при необходимостиloadingиdecoding
Inject не выполняется в контексте mgr, для AJAX (X-Requested-With) и для non-HTML content types.
Пример результата
Исходник:
<img src="assets/images/hero.jpg" alt="Hero">После обработки (варианты 480/768/1024 и full WebP на диске):
<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() не превращает кириллицу в Д. Числовые 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 |
Уже есть srcset | imageoptimizer_respect_existing_srcset=1 (только lazy/decoding) |
| CSS-класс | imageoptimizer_skip_classes (по умолчанию lazy, swiper-lazy, no-optim) |
| Подстрока в URL | imageoptimizer_skip_src_pattern (по умолчанию thumb3x) |
| Явный skip | data-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-изображения (первый экран):
<img src="assets/hero.jpg" alt="" data-imageoptimizer-fetchpriority="high">Или задайте imageoptimizer_skip_lazy_first_images=1 (или больше).
Атрибут sizes
Приоритет:
- Атрибут
sizesна<img> data-imageoptimizer-sizesimageoptimizer_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:
$modx->setPlaceholder('imageoptimizer.skip_html_cache', true);Ручной вывод в шаблонах
Варианты лежат рядом с оригиналом в media source:
| Тип | Пример пути |
|---|---|
| Full WebP | image.jpg.webp |
| Width 768 WebP | image.768.webp |
| AVIF | image.768.avif |
Шаблон имени: imageoptimizer_variant_pattern (плейсхолдеры {basename}, {width}, {ext}).
<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><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 править не нужно.
Связанные разделы
- Системные настройки — все ключи inject
- Совместимость — Thumb3x, MS3
- Решение проблем — если inject не срабатывает
