Squoosh CLI решает задачу массовой оптимизации изображений из командной строки: сжимает и перекодирует файлы в MozJPEG, WebP, AVIF, JPEG XL, WebP2 и оптимизированный PNG, умеет перед кодированием менять размер, сокращать палитру и поворачивать изображение. Инструмент полезен разработчикам, владельцам сайтов, техническим редакторам и всем, кому нужно одинаково обработать десятки или сотни файлов, повторить параметры в скрипте или встроить подготовку картинок в сборку проекта без ручного открытия каждого изображения.
- Ретушь портретов и пластика лица
- Удаление и замена фона
- Пакетная обработка сотен снимков
- Нет визуального предпросмотра
- Большие пакеты могут упереться в память
- Параметры кодеков требуют JSON/JSON5
Что именно делает Squoosh CLI
Squoosh CLI — консольный интерфейс к набору WebAssembly-кодеков семейства Squoosh. В отличие от визуального редактора, здесь нет холста с разделителем «до/после», ползунков и кнопки сохранения. Пользователь описывает операцию аргументами командной строки, передаёт один или несколько входных файлов, а программа декодирует изображения, при необходимости выполняет операции подготовки и передаёт результат выбранному кодеку. Такой подход удобен не потому, что команда короче нескольких кликов, а потому, что одну и ту же команду можно повторить без изменений на большой коллекции.
Базовый синтаксис имеет вид squoosh-cli [options] <files...>. Аргументы файлов обязательны: одной установки и выбора кодека недостаточно. В качестве входа обычно передают конкретные пути или шаблон, который разворачивает оболочка. На Unix-подобных системах выражение вроде images/*.jpg превращается оболочкой в список файлов до запуска Squoosh CLI. В Windows поведение зависит от используемой оболочки, поэтому одинаковая строка в Bash, PowerShell и классическом cmd может дать разные результаты. Это важная особенность: сама программа работает со списком полученных путей и не является универсальным файловым менеджером с собственным браузером каталогов.
CLI умеет выдать несколько форматов из одного источника в одном запуске. Например, можно запросить WebP и AVIF одновременно, чтобы получить две версии картинки для разных вариантов доставки на сайт. Можно сначала уменьшить ширину, затем закодировать результат двумя кодеками. Это отличает конвейер от утилит, где каждая команда обязательно создаёт только один выходной файл. При этом каждое дополнительное кодирование увеличивает вычислительную нагрузку: программа должна выполнить отдельную операцию сжатия для каждого выбранного выходного формата.
Внутри используется пул рабочих потоков. Идея проста: несколько изображений могут обрабатываться параллельно, поэтому пакет из файлов лучше загружает многоядерный процессор, чем последовательный цикл из одиночных запусков. Однако сам проект прямо не позиционировал CLI как рекордсмена скорости. Кодеки выполняются через WebAssembly, а память распределяется одновременно для декодированных пикселей и нескольких рабочих задач. Поэтому эффективность зависит не только от количества ядер, но и от разрешения исходников, кодека, числа одновременных файлов и доступной оперативной памяти.
Установка и начало работы
Официальный пакет распространялся в npm под именем @squoosh/cli. Есть два типичных способа запуска. Первый — через npx, когда пакет можно вызвать без постоянной глобальной установки: npx @squoosh/cli --help. Второй — установить пакет глобально командой npm i -g @squoosh/cli, после чего доступна команда squoosh-cli. Для разового теста удобнее npx; для повторяющегося локального сценария короче использовать глобальную команду.
Перед установкой нужен Node.js и npm. Здесь есть практическое ограничение: последняя опубликованная ветка оригинального CLI ориентировалась на старые поддерживаемые версии Node.js. В зависимостях встречается проверка движка, рассчитанная на Node 12, 14 и 16; в отчётах пользователей установка на более новые ветки могла блокироваться или приводить к несовместимому поведению. Если на современной машине пакет не запускается, не стоит первым делом менять параметры кодека: сначала проверьте версию Node.js и сообщение менеджера пакетов. Для старого CLI разумно выделить отдельное окружение через менеджер версий Node, контейнер или изолированный CI-образ, чтобы не откатывать системную среду всего проекта.
После установки первая полезная команда — squoosh-cli --help. Она показывает не только синтаксис, но и фактический список доступных препроцессоров и кодеков. В оригинальном пакете присутствуют --resize, --quant, --rotate, а также энкодеры --mozjpeg, --webp, --avif, --jxl, --wp2 и --oxipng. Опции -d и --output-dir задают папку вывода, -s и --suffix добавляют суффикс к имени, а параметры автооптимизации ограничивают число итераций и целевую дистанцию Butteraugli.

Для проверки окружения полезно также запросить версию. В разных выпусках поведение короткого флага версии менялось, поэтому надежнее ориентироваться на подсказку именно установленного экземпляра. Если команда помощи стартует, а кодирование падает, значит проблема уже не в нахождении исполняемого файла, а в параметрах, декодере, WebAssembly-модуле или совместимости среды выполнения.

Первое безопасное преобразование
Начинать лучше не с перезаписи рабочей папки, а с отдельного каталога вывода. Создайте тестовую директорию и передайте один небольшой файл. Например: squoosh-cli --mozjpeg '{"quality":75}' -d output photo.png. Команда декодирует PNG, кодирует его MozJPEG и запишет JPEG в output. Такой тест одновременно проверяет чтение исходника, загрузку WebAssembly-кодека, парсинг конфигурации и права на запись.
Пустой объект конфигурации {} означает использование значений по умолчанию соответствующего кодека. Это полезный приём, когда нужно быстро проверить работоспособность: squoosh-cli --webp '{}' -d output photo.jpg. После успешного запуска можно добавлять параметры качества. Если сразу вставить длинный объект с десятками ключей, сложнее понять, какой именно ключ вызвал ошибку.
Не путайте отсутствие конфигурации и пустую конфигурацию. Некоторые параметры командной строки объявлены как опции с конфигурационным аргументом, поэтому запись --mozjpeg без объекта рядом может быть разобрана не так, как ожидается. Характерная ошибка старого CLI — не всегда понятное сообщение при некорректной форме аргумента. Поэтому в практических рецептах лучше явно указывать '{}' или объект с нужными значениями.
Как устроена команда
Команду удобно читать слева направо как конвейер. Сначала идёт исполняемый файл — npx @squoosh/cli либо squoosh-cli. Затем перечисляются операции подготовки изображения. После них — один или несколько энкодеров. Далее можно задать папку вывода и суффикс, а в конце передать файлы. Формальный парсер допускает иной порядок многих опций, но единый стиль облегчает поддержку скриптов.
Пример с уменьшением ширины и кодированием WebP:
squoosh-cli
--resize '{"width":1200}'
--webp '{"quality":75}'
-d dist
images/*.jpg
В этом случае оболочка сначала превращает images/*.jpg в список имён, затем каждый файл декодируется, проходит resize до ширины 1200 пикселей с вычислением второй стороны, после чего кодируется в WebP. Если исходник уже меньше целевого размера, старый препроцессор не предоставляет отдельной семантики «только уменьшать» уровня современных библиотек, поэтому перед массовой обработкой стоит проверить результат на нескольких типичных файлах.
Аргументы конфигурации разбираются в формате, допускающем JSON5-подобную запись, но перенос команды между оболочками может сломать кавычки. На Bash и zsh удобно оборачивать объект в одинарные кавычки. В PowerShell правила отличаются, а в cmd одинарные кавычки не играют ту же роль. Если команда скопирована из документации и падает на первом символе объекта, проблема часто не в кодеке, а в том, как оболочка передала кавычки и фигурные скобки процессу Node.js.
Папка вывода и имена файлов
-d или --output-dir задаёт каталог назначения. По умолчанию используется текущая директория. Для рабочих коллекций это рискованно: выходной файл может получить имя, совпадающее с существующим, особенно если вход и выход имеют одинаковое расширение. Самый безопасный сценарий — всегда направлять первые запуски в отдельную папку вроде optimized.
-s или --suffix добавляет текст к базовому имени. Команда squoosh-cli --mozjpeg '{"quality":75}' -s -min photo.png создаёт файл с суффиксом перед расширением JPEG. Суффикс особенно полезен, когда исходники и результаты лежат рядом или когда нужно визуально отличить несколько профилей — например -thumb, -web и -retina. Если форматы разные, суффикс не обязателен, но всё равно помогает избежать путаницы при повторных запусках.
Перед обработкой большой папки проверьте, существует ли каталог назначения и имеет ли текущий пользователь право записи. Ошибка разрешений может выглядеть как сбой инструмента, хотя кодирование прошло нормально. В контейнерах важно учитывать UID/GID: файлы, созданные процессом от root, затем могут оказаться неудобными для редактирования с хоста. В CI лучше явно создавать каталог и не полагаться на случайное состояние рабочего пространства.
Выбор входных файлов и пакетная обработка
Сильная сторона Squoosh CLI — обработка списка файлов одним запуском. Однако «пакетная обработка» здесь не означает встроенный диалог выбора каталога. Практически вы передаёте несколько путей или используете возможности оболочки. На Bash команда squoosh-cli --webp '{}' -d output *.png обработает PNG-файлы текущей директории, если шаблон совпал с ними. При необходимости рекурсии удобнее сначала сформировать список средствами оболочки или find, а затем передавать файлы порциями.
Следите, чтобы шаблон не захватил подпапки. В старых выпусках встречалась ошибка EISDIR: illegal operation on a directory, read, когда в набор аргументов попадал каталог и программа пыталась прочитать его как файл. Это легко воспроизвести шаблоном, который совпадает и с файлами, и с директориями. Исправление — сузить маску по расширению, отделить исходники от подпапок или предварительно сформировать список только обычных файлов.
В Windows отдельная сложность — разворачивание glob-шаблонов. В Bash маска обычно раскрывается до запуска программы. В классическом cmd это поведение не гарантируется, а PowerShell имеет собственные правила. Поэтому сценарий, который без изменений работает на Linux, может на Windows получить буквальную строку *.jpg вместо списка. Для воспроизводимого процесса используйте оболочку, где поведение шаблонов известно, либо явно перечисляйте файлы из скрипта.
При успешной пакетной обработке CLI выводит число завершённых файлов, исходный размер, имя результата, новый размер и отношение к исходнику. Это не художественная оценка качества, а технический отчёт, который удобно читать в логе. Его можно сохранять вместе с журналом сборки, чтобы видеть, какие файлы прошли кодирование.

После большого пакетного прогона полезно проверить не только консоль, но и состав каталога: совпадает ли количество результатов с количеством исходников, нет ли нулевых файлов, соответствуют ли расширения выбранным кодекам. На локальной машине это можно сделать файловым менеджером, но в автоматизации лучше использовать подсчёт файлов и проверку кода завершения процесса.

Другой реальный сценарий — многодесятковая серия изображений, где в терминале видны пары «исходник → результат» и процент от исходного размера. Такой журнал особенно удобен для выявления аномалий: если один JPEG после перекодирования неожиданно вырос, его нужно вынести из общего профиля и проверить отдельно, а не делать вывод о качестве всего пакета.

MozJPEG: JPEG для веб-публикации
Опция --mozjpeg создаёт JPEG через MozJPEG. Это рациональный выбор для фотографий, где требуется широкая совместимость и управляемое качество. В конфигурации есть quality, режим progressive, выбор таблиц квантования, настройки субдискретизации цветности и другие низкоуровневые параметры. Для большинства задач начинать стоит с качества и значений по умолчанию, а не переносить в команду весь объект энкодера.
Минимальный пример: squoosh-cli --mozjpeg '{"quality":75}' -d output photo.png. Если источник JPEG, повторное сжатие неизбежно добавляет потери: энкодер работает уже с декодированными пикселями, а не «оптимизирует контейнер без перекодирования». Поэтому храните оригиналы отдельно. Squoosh CLI уместен на этапе производства веб-копий, но не как архиватор единственного мастер-файла.
Параметр progressive определяет прогрессивный JPEG. В стандартных настройках MozJPEG Squoosh использовался прогрессивный режим. В современном браузере это обычно приемлемо, но если потребитель изображения — старое ПО, встроенное устройство или специфический конвейер, проверьте поддержку на целевой стороне. Аналогично параметры цветности и таблиц квантования лучше менять только при понимании их эффекта.
В старых выпусках CLI были сообщения о различиях между результатом браузерного Squoosh и командной строки при одинаково выглядящих настройках. Причина могла быть связана с декодированием и преобразованием цветового пространства. Поэтому не используйте принцип «скопировал параметры — получил байт-в-байт тот же файл» как гарантию. CLI и браузерная версия могут проходить через разные пути декодирования, особенно на старых сборках.
WebP: универсальный формат для веба
--webp создаёт WebP и принимает большой набор параметров libwebp. Базовый профиль можно задать как {"quality":75}, а для теста использовать пустой объект. В конфигурации также встречаются method, параметры фильтра, lossless, качество альфа-канала, near-lossless и другие флаги. С точки зрения эксплуатации важно разделять режимы: обычный lossy WebP для фотографий и lossless/near-lossless для графики решают разные задачи.
Не стоит переносить длинный объект из чужой статьи без проверки полей. Squoosh CLI старой ветки зависел от конкретной версии кодека, и отдельные опции менялись со временем. Чем больше явно задано параметров, тем выше вероятность несовместимости. Стабильнее фиксировать только те значения, которые действительно нужны для вашего профиля, а остальные оставлять значениями по умолчанию установленного пакета.
Практический профиль для фронтенда выглядит так: сначала уменьшить изображение до реальной максимальной ширины компонента, затем выполнить WebP-кодирование. Уменьшение геометрии часто даёт больший выигрыш, чем агрессивное снижение quality. Например, исходник камеры шириной 6000 пикселей редко нужен в карточке шириной 1200 пикселей. Сначала уберите лишние пиксели, затем подбирайте качество по визуальной проверке.
Если WebP получается больше исходного PNG или JPEG, это не обязательно ошибка. Формат не гарантирует уменьшения для любого содержания. Небольшая уже оптимизированная картинка, простая графика или повторное перекодирование могут дать отрицательный эффект. Автоматизация должна сравнивать размеры и при необходимости оставлять исходник, а не безусловно заменять файл только потому, что расширение современнее.
AVIF: компактные файлы с более тяжёлым кодированием
--avif включает AVIF-кодек. В оригинальной конфигурации важным параметром был cqLevel, а не универсальный quality, который встречается у JPEG и WebP. Это принципиальный момент. Попытка передать {"quality":40} выглядит логично, но старый AVIF-энкодер Squoosh использовал другую схему параметров. Для воспроизводимого результата нужно смотреть фактические ключи именно установленного пакета.
У AVIF-кодирования есть параметры скорости и качества, а также настройки тайлов и субдискретизации. Чем тяжелее профиль, тем больше времени процессора потребуется. Для пакетной обработки сотен больших фотографий это особенно заметно. Если ваша задача — быстрый build в каждую минуту разработки, разумно разделить этапы: тяжёлое кодирование выполнять при подготовке медиатеки, а не при каждом горячем обновлении проекта.
С AVIF у старого CLI зафиксированы реальные проблемные случаи. Пользователи получали ошибки привязок WebAssembly и зависание после старта кодирования, а также путались из-за передачи поля quality, не соответствующего ожидаемой схеме. Поэтому рецепт диагностики такой: сначала пустая конфигурация {}, затем один документированный параметр, затем остальные по одному. Если --avif '{}' работает, а длинный объект — нет, причина почти наверняка в конфигурации, а не в чтении файла.

Для AVIF также полезно помнить о совместимости декодирования входа. Не каждый AVIF, созданный сторонним кодировщиком, одинаково принимался старым декодером Squoosh CLI. Если входной AVIF помечается как неподдерживаемый, сначала проверьте его внешним декодером и попробуйте промежуточный PNG, не уничтожая оригинал. Это диагностический шаг, а не рекомендация постоянно делать лишнее перекодирование.
JPEG XL и WebP2: экспериментальные направления
Опции --jxl и --wp2 присутствовали в командной строке оригинального пакета и соответствовали экспериментальным кодекам Squoosh того периода. JPEG XL в конфигурации использовал параметры вроде quality, speed, progressive и near-lossless. WebP2 имел собственные настройки качества, усилия кодирования и альфа-канала. Наличие флага в CLI означает возможность создать файл, но не гарантирует, что этот формат уместен для продакшена.
Перед выбором JXL или WP2 нужно проверять декодирование на целевых клиентах. Для сайта важна поддержка браузеров и инфраструктуры доставки; для внутреннего архива — поддержка программ, которые будут открывать файл через несколько лет. Если формат не принят вашим окружением, выигрыш в размере не компенсирует операционные сложности. Поэтому эти энкодеры лучше рассматривать как средство тестирования и сравнения, если ваш конвейер их действительно понимает.
Автооптимизатор в документации демонстрировался на WebP2 командой с конфигурацией auto. Это хороший пример механики, но не указание использовать WebP2 по умолчанию. Само слово auto запускает подбор параметра кодека под целевую дистанцию Butteraugli, а не выбирает лучший формат для вашего проекта.
OxiPNG: оптимизация PNG
--oxipng создаёт PNG и применяет OxiPNG к сформированному изображению. В старой конфигурации ключевым параметром был уровень оптимизации level. Пустой объект использует значение по умолчанию. В отличие от MozJPEG, здесь задача связана с без потерь оптимизируемым PNG-контейнером после декодирования и возможных препроцессоров.
Для интерфейсной графики PNG часто сочетают с --quant. Но важно понимать порядок смысла: сокращение палитры уже может быть потерей цветовой информации, даже если итоговый PNG технически закодирован без потерь относительно квантованного изображения. Поэтому «PNG» не автоматически означает «исходные пиксели сохранены». Если включена квантование палитры, визуальный результат нужно оценивать так же внимательно, как при lossy-кодировании.
Типичный сценарий для иконок и скриншотов: уменьшить количество цветов до разумного значения, затем запустить OxiPNG. На фотографиях агрессивная палитра быстро создаёт постеризацию и шум на градиентах, поэтому там этот путь обычно хуже JPEG/WebP/AVIF. Инструмент не знает семантики изображения; выбор стратегии остаётся на пользователе.
Resize: изменение размеров до сжатия
--resize выполняется до энкодера. В исходном коде препроцессора поддерживались алгоритмы triangle, catrom, mitchell и lanczos3; значением по умолчанию для метода был lanczos3. Если указана только ширина или только высота, вторая сторона рассчитывается с сохранением пропорции. Если заданы обе стороны, старый механизм мог растянуть изображение к указанным размерам.
Это важнее, чем кажется. В браузерном интерфейсе существовало понятие fit method, но в CLI были случаи, когда ожидаемое поведение contain не срабатывало и результат растягивался. Если вам нужен строгий режим «вписать без искажения», проверьте конкретную комбинацию на контрольном кадре. Для безопасного сохранения пропорций проще передавать только одну размерность, если бизнес-задача это допускает.
Параметры premultiply и linearRGB связаны с математикой ресайза и прозрачностью. Их не стоит менять случайно. Premultiply особенно важен для корректной интерполяции полупрозрачных пикселей по краям объектов. Linear RGB влияет на пространство, в котором выполняется смешивание при масштабировании. Значения по умолчанию были выбраны разработчиками как рабочий компромисс; меняйте их только для контролируемого теста.
Для сайтов лучший размер — не «как можно меньше», а размер, соответствующий месту показа и плотности экрана. Если карточка отображается максимум в 640 CSS-пикселей, может понадобиться вариант 1280 пикселей для экранов 2x, но исходник 6000 пикселей почти наверняка избыточен. Squoosh CLI удобен тем, что этот размер можно зафиксировать в скрипте и применять к каждой новой партии.
Quant: сокращение палитры
--quant уменьшает число используемых цветов. В коде CLI параметр назывался numColors, а также присутствовал dither. Это один из случаев, где нельзя бездумно переносить поля из версии веб-интерфейса: в старом Squoosh встречалось несоответствие между названием параметра в команде, скопированной из UI, и тем, что ожидал CLI. В практическом отчёте рабочим было numColors вместо maxNumColors.
Квантование полезно для схем, интерфейсных скриншотов, пиктограмм, иллюстраций с ограниченной палитрой. Для фотографий оно быстро приводит к ступенькам на небе, коже и мягких тенях. Dither маскирует полосы добавлением пространственно распределённого шума, но сам шум тоже влияет на сжатие. Поэтому число цветов и dithering подбирают вместе.
Пример: squoosh-cli --quant '{"numColors":128,"dither":1}' --oxipng '{"level":2}' -d output icon.png. Перед тем как распространять такой профиль на всю папку, соберите набор разных изображений: плоская графика, градиент, мелкий текст, полупрозрачность. Один логотип может выглядеть отлично при 32 цветах, а другой потеряет фирменный оттенок.
Rotate: поворот по шагам 90 градусов
--rotate — ещё один препроцессор. В старой реализации конфигурация использовала numRotations, а угол получался как число поворотов, умноженное на 90 градусов. Значения 1, 2 и 3 соответствуют 90, 180 и 270 градусам. После поворота на 90 или 270 ширина и высота меняются местами.
Поворот нужно отличать от автоматической ориентации по EXIF. Старый CLI декодирует пиксели и не является полнофункциональным менеджером метаданных. В репозитории были сообщения о том, что JPEG после обработки менял визуальную ориентацию. Если коллекция приходит с камер и телефонов, где положение кадра хранится в теге Orientation, заранее проверьте, как ваш декодер интерпретирует эти файлы. Для критичных архивов сначала нормализуйте ориентацию инструментом, который явно работает с EXIF.
Несколько выходных форматов за один запуск
CLI позволяет перечислить более одного энкодера. Команда вида squoosh-cli --webp '{"quality":75}' --avif '{}' -d output photo.png создаёт версии в двух форматах. Для фронтенда это удобно: из единого исходника можно получить набор альтернатив и затем использовать picture или серверную negotiation-логику.
Вместе с resize это превращается в простой генератор производных ресурсов. Однако CLI не умеет описывать матрицу «три ширины × два формата» одним декларативным конфигурационным файлом. Для нескольких размеров обычно делают несколько вызовов команды с разными --resize и суффиксами. Такой подход многословен, но прозрачен и легко переносится в shell-скрипт или npm scripts.
Например, можно последовательно создать варианты:
squoosh-cli --resize '{"width":640}' --webp '{"quality":75}' -s -640 -d dist images/*.jpg
squoosh-cli --resize '{"width":1280}' --webp '{"quality":75}' -s -1280 -d dist images/*.jpg
squoosh-cli --resize '{"width":1920}' --webp '{"quality":75}' -s -1920 -d dist images/*.jpg
Здесь кодирование выполняется трижды, зато имена предсказуемы. Если изображения добавляются регулярно, команды лучше вынести в скрипт и запускать только для новых или изменённых файлов. Сам Squoosh CLI не ведёт кэш сборки и не сравнивает хеши, поэтому эту задачу должен решать внешний build-инструмент.
Автооптимизатор и Butteraugli
Squoosh CLI имеет экспериментальный автооптимизатор. Вместо объекта параметров энкодеру можно передать auto. Тогда инструмент несколько раз кодирует изображение, изменяя основной параметр качества, и пытается приблизиться к целевой дистанции Butteraugli. Количество попыток ограничивает --max-optimizer-rounds, по умолчанию использовалось 6. Цель задаёт --optimizer-butteraugli-target, по умолчанию 1.4.
Butteraugli — перцептивная метрика различия изображений. В контексте автооптимизатора большее целевое расстояние допускает более заметные отличия и потенциально более сильное сжатие. Однако это не «оценка качества от 0 до 100». Она не заменяет проверку человеком, особенно для текста, UI-скриншотов, медицинских или научных изображений, где отдельный артефакт может быть важнее среднего перцептивного расстояния.
Автооптимизация дороже фиксированного профиля: один файл кодируется несколько раз. Если обработка идёт в CI и время сборки критично, заранее выбранное качество часто практичнее. Авто режим полезен при подготовке ограниченного набора ключевых изображений или при первоначальном подборе параметров, после чего можно зафиксировать найденный диапазон.
В старых версиях были ошибки, при которых изменение Butteraugli target не влияло на ожидаемый результат некоторых кодеков. Поэтому не принимайте сам факт наличия флага за доказательство его корректной работы в конкретной версии. Сравните файлы по размеру и визуально на нескольких значениях. Если выход идентичен при экстремально разных целях, используйте явный параметр качества кодека и зафиксируйте рабочую версию пакета.
Рабочий сценарий для изображений сайта
Рациональная схема начинается с мастер-изображений, которые не изменяются CLI. Создайте отдельную папку src-images и каталог public/images для производных файлов. Затем определите максимальные размеры компонентов: например, 1280 пикселей для крупных карточек, 640 для превью. Не начинайте с выбора качества — сначала уберите избыточное разрешение.
Для фотографий можно использовать WebP или MozJPEG как базовый выход и AVIF как дополнительный, если ваша система доставки его использует. Для логотипов и интерфейсной графики чаще уместен PNG/OxiPNG, иногда с аккуратным quant. Один профиль на все изображения почти всегда неоптимален: фотографии, скриншоты и плоские иллюстрации по-разному реагируют на кодеки.
После первого прогона соберите контрольную страницу, где изображения показаны в реальном размере и на типичном фоне. Оценивайте не только центральную область, но и градиенты, волосы, мелкий текст, диагональные линии, полупрозрачные края. Если артефакты заметны в рабочем масштабе, увеличьте качество или смените формат. Если нет — смотрите на размер файла и время кодирования.
Затем закрепите параметры в репозитории как команду, а не в памяти сотрудника. Например, в package.json можно создать scripts для каждого класса изображений. Так новый участник проекта запускает тот же профиль. Поскольку Squoosh CLI старый и зависит от конкретной среды Node, рядом стоит зафиксировать и версию runtime, например через контейнер или менеджер версий.
Сценарий для медиатеки из сотен фотографий
Большая медиатека требует осторожности из-за потребления памяти. Декодированный 24-мегапиксельный JPEG занимает в памяти намного больше, чем его файл на диске: RGBA-буфер требует примерно четыре байта на пиксель ещё до дополнительных копий и WebAssembly-структур. Если одновременно запустить много таких кадров, процесс может исчерпать память даже на машине, где «файлы занимают всего несколько гигабайт».
В официальном трекере описывался случай с примерно двумя сотнями изображений и ошибкой WebAssembly.Memory(): could not allocate memory. Это не означает, что у CLI есть фиксированный лимит в конкретное число файлов: нагрузка зависит от разрешения, формата и числа потоков. Практический вывод — делить большие коллекции на порции и контролировать память, а не передавать весь архив одной командой.
Можно обрабатывать по 10–30 файлов в цикле внешнего скрипта, особенно если исходники крупные. Даже если общий процесс займёт немного дольше, вероятность падения на середине ниже. Для автоматизации важно также удалять временные результаты неудачного запуска или писать в чистый каталог с последующим атомарным переносом только после успешной проверки.
Если цель — одноразовая массовая миграция десятков тысяч файлов, Squoosh CLI не обязательно лучший инструмент. Специализированные нативные конвейеры, ImageMagick или решения на libvips обычно удобнее по контролю памяти и поддержке. Сильная сторона Squoosh CLI — воспроизвести знакомые кодеки Squoosh и автоматизировать умеренные партии, а не заменить полноценную DAM-систему.
Скрипты и повторяемость
Консольный инструмент раскрывается в скриптах. Вместо копирования длинной команды в терминал создайте файл, где параметры видны в системе контроля версий. Для Bash это может быть несколько строк с переменными INPUT, OUTPUT и профилем энкодера. Для Node.js можно сформировать список файлов через файловую систему и вызывать процесс с массивом аргументов, избегая проблем с кавычками.
Не собирайте пользовательские пути в одну строку без экранирования. Если в имени каталога есть пробелы, амперсанд или другие специальные символы, оболочка может разделить аргументы. Безопаснее передавать аргументы массивом через API запуска процессов или аккуратно цитировать каждую переменную. Это общая практика командной строки, а не особенность Squoosh.
Профили качества стоит именовать по назначению, а не по числу: article-photo, hero, thumbnail. Число 75 само по себе не говорит, для чего оно выбрано. Если через год команда сменит кодек, смысл «hero» останется, а число качества может измениться.
Squoosh CLI не имеет встроенного декларативного файла конфигурации, который бы описывал сложную матрицу форматов и размеров. Такая возможность запрашивалась пользователями как отдельная функция. Поэтому конфигурацию обычно хранят во внешнем скрипте или npm scripts. Для небольшого проекта это не проблема; для крупного медиаконвейера отсутствие собственного конфиг-файла увеличивает объём обвязки.
Использование в CI/CD
CLI можно запускать в CI, но старую зависимость следует контейнеризовать или жёстко фиксировать. Если агент сборки автоматически обновится с Node 16 на Node 20+, ранее работающий пакет может перестать устанавливаться или загрузить WebAssembly иначе. Воспроизводимость важнее удобства «latest».
Не запускайте тяжёлую оптимизацию каждого изображения на каждой сборке, если исходники не менялись. Это тратит процессорное время и удлиняет обратную связь. Лучше считать хеш исходника и параметров или поручить кэш системе сборки. Когда меняется только JavaScript, изображения должны попадать из кэша.
Параллелизм CI тоже требует контроля. Сам Squoosh CLI использует worker pool, поэтому запуск нескольких экземпляров одновременно может умножить число потоков и память. Если агент имеет 2 CPU и 4 ГБ RAM, четыре параллельных job с AVIF могут работать хуже одного последовательного этапа. Настраивайте уровень параллельности на уровне pipeline с учётом внутреннего пула.
После кодирования проверяйте код завершения и наличие ожидаемых файлов. Хороший pipeline падает, если результат не создан, а не продолжает сборку с пустой папкой. Для критичных ресурсов можно дополнительно проверять, что размер файла ненулевой и формат определяется независимым инструментом.
Производительность: что можно ожидать без выдуманных цифр
Проект сам указывал, что Squoosh CLI не стремился быть самым быстрым компрессором. Его ценность — доступ к тем же классам кодеков через WebAssembly и возможность параллельно применить профиль к нескольким файлам. Поэтому корректное сравнение производительности нужно проводить на вашей коллекции, а не переносить чужие числа.
На скорость влияют четыре группы факторов. Первая — разрешение и тип исходника: декодирование огромного JPEG дороже маленькой иконки. Вторая — препроцессоры: resize и quant добавляют работу. Третья — сам энкодер и его effort/speed. Четвёртая — число параллельных файлов и объём памяти. AVIF или JXL с тяжёлыми настройками могут быть значительно медленнее JPEG, но конкретное отношение зависит от сборки кодека и CPU.
Чтобы измерить свой сценарий, возьмите репрезентативный набор из 20–50 файлов разных типов. Запускайте каждый профиль несколько раз в одинаковой среде, отдельно фиксируйте суммарное время, пиковую память и размер результата. Не смешивайте первое выполнение с последующими, если менеджер пакетов ещё скачивает зависимости. Для CI дополнительно учитывайте время установки npm-пакета.
Параллельный вывод прогресса может создавать ощущение, что программа «зависла», когда один тяжёлый файл долго остаётся последним. Ориентируйтесь на загрузку CPU, память и лог ошибок. Если процесс перестал продвигаться после исключения, это уже характерный сбой старого CLI, а не просто медленное кодирование.
Память и worker pool
Worker pool позволяет кодировать несколько файлов одновременно. Но изображение после декодирования представлено большим несжатым буфером. Для кадра 6000×4000 один RGBA-буфер — около 96 миллионов байт без учёта накладных расходов. Если параллельно существуют исходный буфер, промежуточный resize, данные энкодера и несколько workers, реальное потребление может быть кратно размеру файла на диске.
Отсюда следует практическое правило: оценивайте память по пикселям, а не по мегабайтам JPEG. Десять фотографий по 5 МБ могут оказаться тяжелее для RAM, чем сотня небольших PNG-иконок. Если появляются ошибки WebAssembly memory, уменьшите размер партии, предварительно уменьшите геометрию другим этапом или выберите инструмент с более явным контролем concurrency.
Старый оригинальный CLI не показывал пользователю удобный флаг ограничения числа одновременно обрабатываемых файлов в основной документации. В поздних форках такой параметр добавлялся, но это уже другой продукт. Не приписывайте его @squoosh/cli от GoogleChromeLabs. Для оригинала контроль партии проще делать внешним циклом.
Метаданные, цвет и ориентация
Squoosh предназначен прежде всего для получения оптимизированных пиксельных ресурсов, а не для сохранения полного набора метаданных камеры. В экосистеме Squoosh давно обсуждалось удаление метаданных при обработке. Если EXIF, IPTC, XMP, GPS, авторские поля или ICC-профиль являются частью рабочего процесса, отдельно проверьте их наличие в результате. Не предполагайте, что JPEG→JPEG автоматически сохранит всю служебную информацию.
Для веб-публикации удаление метаданных часто даже уменьшает файл, но для фотобанка это может быть неприемлемо. Хорошая архитектура хранит оригинал с метаданными и создаёт производную веб-копию. Тогда оптимизатор не становится единственным источником правды.
Цветовое пространство тоже требует внимания. В одном из ранних обсуждений разработчик отмечал различие: браузерный путь использовал canvas для преобразования, а CLI опирался на результат декодера. Это объясняет, почему одинаковые настройки могли давать отличия оттенков. Для фирменной графики и фото с широким цветовым охватом проверяйте результат в color-managed просмотрщике.
Ориентация JPEG может зависеть от EXIF. Если после обработки вертикальный снимок оказывается повернут, не пытайтесь лечить это случайным --rotate для всей папки: сначала определите, есть ли тег Orientation и применён ли он декодером. Иначе часть файлов станет правильной, а другая — повернётся лишний раз.
Ошибки конфигурации и кавычек
Самый частый класс проблем — строка конфигурации не дошла до программы в том виде, в каком вы её написали. JSON содержит кавычки, двоеточия, запятые и фигурные скобки; оболочка имеет собственные правила интерпретации. На Bash удобна конструкция '{"quality":75}', потому что одинарные кавычки защищают внутренние двойные. В PowerShell нужно проверить, что строка передаётся как один аргумент.
Ошибка JSON5: invalid character указывает на разбор конфигурации. Сначала сократите объект до {}. Если пустой объект работает, добавляйте пары ключ-значение постепенно. Это быстрее, чем искать ошибку в строке из 500 символов.
Второй тип ошибки — правильный JSON, но неправильный ключ. Пример с AVIF: quality привычен по WebP, однако старый AVIF-конфиг использовал cqLevel. Пример с quant: UI и CLI в отдельных выпусках расходились в названии maxNumColors/numColors. Поэтому ориентируйтесь на схему конкретной версии, а не на название похожего параметра в другом кодеке.
Третий тип — значение правильного ключа имеет неподходящий тип. Некоторые уровни ожидались числом, некоторые сборки могли фактически принимать строку из-за парсинга. Если пример из трекера ошибок противоречит документации, не копируйте обходной путь без теста. Зафиксируйте рабочую команду для вашей версии и добавьте контрольный файл в автоматический тест.
Совместимость Node.js
Для оригинального @squoosh/cli совместимость Node.js — не абстрактная системная характеристика, а часть работоспособности. В одном из официальных issue зависимость @squoosh/lib указывала допустимые ветки 12.5+, 14 и 16 и отклоняла Node 17. Поздние Node меняли реализацию глобального fetch и поведение загрузки локальных WASM, что также влияло на форки.
Если вам нужно воспроизвести старый проект, используйте изолированную среду, где версия Node указана явно. Контейнер особенно удобен для CI: образ содержит Node, npm и CLI, а наружу монтируются только исходники и результаты. Но контейнер не исправляет ошибки самого кодека; он лишь делает среду стабильной.
Не стоит ставить старую ветку Node как системную единственную версию на рабочую станцию. Менеджеры версий позволяют переключаться по проектам. Это снижает конфликт с современными сборщиками, которым, наоборот, нужен новый Node.
Неподдерживаемый формат
Если CLI сообщает, что файл имеет unsupported format, сначала убедитесь, что расширение соответствует содержимому. Простое переименование .jpg в .png не конвертирует данные. Squoosh определяет форматы по сигнатурам, поэтому неверное расширение может не помочь.
В старой библиотеке были декодеры для основных форматов, используемых Squoosh, но набор входов не равен «любому формату, который открывается вашей ОС». RAW-файлы камер, PSD, сложные TIFF и многие специализированные контейнеры не являются задачей Squoosh CLI. Если источник не декодируется, сначала преобразуйте мастер-копию подходящим инструментом в поддерживаемый промежуточный формат без лишних потерь.
Отдельно встречались AVIF-файлы, созданные сторонними сервисами, которые не принимались старым декодером. Это пример того, почему «формат поддерживается» не означает совместимость со всеми вариантами битстрима. Для автоматизации храните тестовый набор сложных файлов и прогоняйте его при изменении версии среды.
Как контролировать качество без встроенного предпросмотра
У CLI нет интерактивного сравнения до/после. Значит, контроль качества нужно построить отдельно. Самый простой метод — открыть исходник и результат рядом в одном масштабе. Для нескольких десятков файлов удобно создать HTML-страницу или контактный лист, где обе версии стоят парами.
Не сравнивайте изображения в масштабе 20% на большом мониторе: многие артефакты исчезнут. Проверяйте хотя бы 100% для критичных областей и реальный CSS-размер, в котором ресурс увидит пользователь. На фотографиях смотрите на волосы, листву, шумное небо, текстуры ткани и градиенты. На скриншотах — на мелкий текст, тонкие линии и однотонные поля.
Размер файла — только одна ось. Выигрыш с 180 КБ до 150 КБ может быть бессмысленным, если появляются заметные артефакты; наоборот, переход с 3 МБ до 300 КБ часто оправдывает небольшие изменения, если изображение предназначено для карточки. Решение зависит от роли ресурса.
Для воспроизводимости сохраняйте небольшой «golden set» изображений. При изменении параметров CLI прогоните именно его и сравните результаты. Так легче заметить регрессию после смены Node, кодека или профиля.
Практические рецепты
JPEG из PNG с контролем качества
Для фотографического PNG, который не требует прозрачности:
squoosh-cli --mozjpeg '{"quality":78}' -d output photo.png
Сначала проверьте, что альфа-канал действительно не нужен. JPEG не поддерживает прозрачность; итоговый вид прозрачных областей зависит от того, как они компонуются до кодирования. Если фон должен быть конкретного цвета, Squoosh CLI не предлагает полноценный compositing-инструментарий, поэтому подготовьте фон заранее.
WebP после уменьшения ширины
squoosh-cli --resize '{"width":1600}' --webp '{"quality":76}' -d output images/*.jpg
Команда подходит для партии фотографий, если 1600 пикселей — осознанный предел. Для мобильных превью лучше делать отдельный меньший вариант, а не заставлять браузер скачивать 1600-пиксельный файл и уменьшать его CSS.
PNG с сокращённой палитрой
squoosh-cli --quant '{"numColors":128,"dither":1}' --oxipng '{"level":2}' -d output ui.png
Этот профиль стоит тестировать на градиентах. Если изображение плоское, число цветов можно уменьшать; если появляются полосы, поднимите лимит или уберите quant.
Два формата из одного изображения
squoosh-cli --webp '{"quality":76}' --avif '{}' -d output hero.png
После этого система публикации должна знать, какой файл отдавать клиенту. CLI только создаёт варианты; HTML, CDN и Content-Type — задача остального проекта.
Суффикс для сохранения нескольких профилей
squoosh-cli --resize '{"width":800}' --mozjpeg '{"quality":78}' -s -card -d output source.jpg
Суффикс помогает не перепутать производные файлы. Для нескольких размеров добавляйте размер в имя: -640, -1280. Это упрощает статическую раздачу без базы метаданных.
Типичные ошибки и способы исправления
| Симптом | Вероятная причина | Что сделать |
|---|---|---|
| missing required argument ‘files’ | Не передан входной файл или опция поглотила аргумент | Добавить явный путь и проверить форму конфигурации |
| JSON5 invalid character | Кавычки изменены оболочкой или объект повреждён | Начать с '{}' и добавлять ключи по одному |
| EISDIR | В список входов попал каталог | Сузить glob до файлов нужного расширения |
| Unsupported format | Нет декодера или файл не соответствует расширению | Проверить сигнатуру и преобразовать в поддерживаемый формат |
| WebAssembly memory error | Слишком большая партия или крупные кадры | Делить обработку на меньшие группы |
| Процесс висит после ошибки | Worker не завершился после исключения | Остановить процесс, упростить команду, обработать один файл |
| Параметр качества не меняет результат | Использован не тот ключ кодека | Проверить схему конкретного энкодера |
| Изображение повернулось | Разное обращение с EXIF Orientation | Нормализовать ориентацию до пакетной обработки |
| Цвет отличается от браузерной версии | Иной путь декодирования/цветового пространства | Сравнить в color-managed просмотрщике |
| Glob не работает на Windows | Оболочка не разворачивает шаблон как Bash | Сформировать список файлов скриптом или сменить shell |
Разбор проблем с зависанием
Если прогресс остановился, сначала смотрите последнюю строку перед зависанием. Если там исключение WebAssembly, BindingError или UnhandledPromiseRejection, ожидание обычно не исправит ситуацию. Завершите процесс и воспроизведите на одном файле. Большая партия скрывает первопричину.
Затем удалите все препроцессоры и оставьте один энкодер с {}. Если базовое кодирование работает, добавьте resize, quant или rotate по одному. После этого добавляйте параметры энкодера. Такой бинарный подход превращает длинную команду в набор проверяемых шагов.
Если один конкретный файл ломает процесс, а остальные проходят, не меняйте глобально профиль. Проверьте формат, разрешение, альфа-канал, метаданные и возможность открыть файл независимым декодером. Возможно, повреждён сам источник или используется редкая вариация контейнера.
Если ломается любой файл, проверяйте среду: Node.js, архитектуру CPU, способ установки, права на каталог, наличие свободной памяти. На Apple Silicon в ранних версиях фиксировались специфические падения. Старый пакет не следует считать гарантированно совместимым со всеми современными платформами только потому, что JavaScript обычно переносим.
Что не умеет Squoosh CLI
У него нет полноценного визуального редактора. Нельзя кистью удалить объект, локально осветлить лицо, заменить фон или собрать коллаж. Это не недостаток реализации по отношению к его назначению: CLI специализируется на кодировании и нескольких подготовительных операциях.
Нет системы слоёв, масок, локальной ретуши, текста и графических элементов. Нет каталогизации фотографий и управления проектами. Нет удобной пакетной схемы с различными правилами для подпапок из коробки. Всё это приходится строить внешними скриптами или выбирать другой класс программы.
Нет гарантии сохранения всех метаданных. Нет интерактивного предпросмотра результата до записи. Нет встроенного механизма «оставить меньший из исходника и результата». Нет современного управления concurrency в исходной документированной версии. Эти ограничения особенно заметны, когда инструмент пытаются использовать как универсальную медиафабрику.
Сравнение с аналогами
Squoosh CLI имеет смысл сравнивать сразу по двум направлениям. С ФотоМАСТЕР он пересекается в базовых операциях подготовки изображений, но предназначение принципиально различается: ФотоМАСТЕР — визуальный фоторедактор с ретушью и творческими инструментами, а Squoosh CLI — автоматизируемый консольный энкодер. С ImageMagick и sharp-cli сравнение прямее, потому что они тоже работают из командной строки и подходят для пакетных конвейеров.
| Задача | Squoosh CLI | ФотоМАСТЕР | ImageMagick | sharp-cli |
|---|---|---|---|---|
| Пакетное кодирование из скрипта | Да, список файлов и worker pool | Пакетная обработка доступна в функциональности редактора | Да, развитая командная строка и mogrify | Да, CLI поверх sharp/libvips |
| Визуальная ретушь портрета | Нет | Да, автоматическая и ручная коррекция | Не основное назначение, GUI нет | Нет |
| Удаление/замена фона | Нет | Да | Можно собирать масками и операциями, но вручную через команды | Есть compositing, но не готовая AI-замена фона |
| Resize | Да, несколько алгоритмов | Да, через редактор | Да, много фильтров и геометрий | Да, развитый resize libvips |
| MozJPEG/WebP/AVIF | Да | Зависит от форматов экспорта редактора | Поддержка зависит от сборки делегатов | JPEG, PNG, WebP, AVIF и другие распространённые форматы |
| PNG-оптимизация OxiPNG | Встроенный энкодер | Не отдельный CLI-кодек | Своя система PNG-сжатия | PNG через libvips |
| Перцептивная автооптимизация Butteraugli | Есть экспериментальный режим | Нет такого CLI-сценария | Нет идентичного режима по умолчанию | Нет идентичного режима по умолчанию |
| Поддержка сложных графических операций | Ограничена resize/quant/rotate | Ориентирована на фото и оформление | Очень широкая | Широкая для серверной обработки |
| Современная поддержка среды | Оригинальный пакет требует старой совместимой Node-среды | Ориентирован на актуальные пользовательские ОС заявленной линейки | Активно развивается | Активно развивается |
Squoosh CLI и ФотоМАСТЕР
ФотоМАСТЕР удобнее, когда задача начинается с визуальной оценки кадра: исправить освещение, ретушировать кожу, скорректировать лицо и фигуру, удалить объект, заменить или размыть фон, добавить эффект. Эти операции требуют человеческого выбора области и результата. Squoosh CLI не пытается их повторять и не имеет соответствующих инструментов.
Squoosh CLI удобнее в другом типе работы: есть заранее определённый профиль, например «все новые изображения раздела уменьшить до 1280 пикселей и сделать WebP». Здесь ручной интерфейс только добавляет повторяющиеся действия. Команда фиксируется один раз и затем выполняется одинаково.
Пакетная обработка есть и в старших возможностях ФотоМАСТЕР, но это не превращает редактор в CI-инструмент. Если результат должен запускаться при сборке сайта, CLI-подход естественнее. Если перед экспортом требуется ретушь десятка портретов, визуальный редактор естественнее. Эти продукты закрывают разные стадии одного возможного рабочего процесса.
Squoosh CLI и ImageMagick
ImageMagick значительно шире по операциям: crop, blur, sharpen, compositing, текст, геометрические преобразования, работа с каналами, профилями и множеством форматов. Его magick и mogrify десятилетиями используются для пакетной обработки. Если нужно построить сложное преобразование пикселей, ImageMagick обычно гибче.
Squoosh CLI проще, когда важны конкретные кодеки Squoosh и небольшой набор препроцессоров. Команда с WebP или AVIF близка к модели параметров веб-приложения. Но за эту простоту приходится платить меньшей универсальностью и проблемами старого runtime.
ImageMagick может читать более сотни форматов при наличии соответствующих делегатов, тогда как Squoosh CLI имеет намного более узкий набор декодеров. Для смешанного архива это критично. С другой стороны, ImageMagick имеет собственные нюансы сборки: наличие AVIF/WebP/HEIC зависит от подключённых библиотек, поэтому в контейнере тоже нужно фиксировать окружение.
Squoosh CLI и sharp-cli
sharp-cli построен вокруг библиотеки sharp и libvips. Он ориентирован на высокопроизводительную серверную обработку распространённых веб-форматов, умеет resize и другие трансформации, а современная ветка sharp поддерживает актуальные Node.js. Для нового проекта это часто более естественная основа, особенно если экосистема уже использует JavaScript.
Squoosh CLI отличается набором встроенных WASM-кодеков и исторически тесной связью с Squoosh. Если нужно воспроизвести старый профиль проекта или использовать OxiPNG/JXL/WP2 именно в форме, представленной в Squoosh того периода, у него есть своя ниша. Для долгоживущего нового production-конвейера следует отдельно оценить поддержку и обновления.
sharp корректно работает с ICC-профилями и альфа-каналом в рамках своей библиотеки и предоставляет большой API. Squoosh CLI гораздо меньше по интерфейсу. Это делает его легче для небольшого скрипта, но сложнее для нетипичных требований вроде compositing, extraction, автоматической ориентации и сложной обработки метаданных.
Когда выбирать Squoosh CLI
Инструмент подходит, если у вас уже есть известный профиль Squoosh, пакет умеренного размера и стабильная совместимая Node-среда. Он удобен для учебного проекта, локальной подготовки ассетов, миграции старого сайта, воспроизведения существующего build-процесса и простых скриптов «resize + один или несколько кодеков».
Он менее удобен, если нужна современная долгосрочно поддерживаемая инфраструктура без фиксации старого Node, огромные архивы, богатые графические операции, точная работа с метаданными или гарантированная кроссплатформенность shell-команд. В этих случаях сначала сравните ImageMagick, libvips/sharp и специализированные энкодеры.
Если задача чисто ручная и визуальная — исправить конкретную фотографию, убрать дефект, заменить фон — командная строка вообще не даёт преимущества. Здесь логичнее редактор вроде ФотоМАСТЕР. Squoosh CLI проявляет себя там, где решение уже принято и его надо повторить много раз.
Как подготовить стабильный профиль
Сначала выберите 10–20 изображений, представляющих реальные материалы проекта: светлую фотографию, тёмную, портрет, пейзаж с листвой, скриншот с мелким текстом, иллюстрацию с градиентом, PNG с прозрачностью. Не подбирайте параметры на одном красивом кадре.
Определите геометрию каждого класса. Для hero может быть 1920 или 1600 пикселей, для карточки 800–1200, для превью меньше. После этого выберите формат. Для фотографии протестируйте MozJPEG, WebP и AVIF. Для интерфейсной графики сравните WebP lossless и PNG/OxiPNG с quant и без него.
Затем подберите качество. Меняйте один параметр за раз. Записывайте размер результата и наблюдения. Не ищите «магическое значение качества», которое одинаково хорошо для всех кодеков: шкалы не эквивалентны между JPEG, WebP, AVIF и JXL.
Когда профиль выбран, сократите конфигурацию до минимального набора явно изменяемых ключей. Длинная команда с двадцатью значениями по умолчанию хуже поддерживается и сильнее привязана к версии. Зафиксируйте версию CLI и Node. Добавьте golden set в тесты.
Проверка результатов перед публикацией
Первое — убедиться, что все ожидаемые файлы созданы. Второе — проверить их тип независимым инструментом, а не только расширение. Третье — сравнить размеры и отметить файлы, которые выросли. Четвёртое — визуально просмотреть репрезентативную выборку.
Если часть результатов больше исходников, автоматический pipeline может выбирать меньший файл. Но сравнивать нужно только функционально взаимозаменяемые варианты. PNG с прозрачностью нельзя заменить JPEG только из-за меньшего размера, если прозрачность нужна. Аналогично AVIF нельзя оставить единственным файлом, если целевой клиент его не декодирует.
Веб-проекту также нужна корректная разметка и заголовки MIME. Squoosh CLI не конфигурирует сервер. После появления .avif или .webp убедитесь, что хостинг отдаёт правильный Content-Type и CDN не блокирует расширение.
Миграция существующего скрипта
Если в проекте уже есть @squoosh/cli, сначала зафиксируйте текущий результат перед любыми обновлениями. Сохраните версию Node, npm, CLI и контрольные выходные файлы. Старый скрипт может зависеть не только от явных параметров, но и от конкретных значений по умолчанию кодека.
После переноса в контейнер сравните размеры и хеши. Для lossy-кодеков байт-в-байт совпадение желательно, если версии идентичны, но при смене платформы или сборки могут быть различия. Критично проверить визуальное качество и функциональность, а не только checksum.
Если решено перейти на другой инструмент, мигрируйте по профилям. Сначала воспроизведите resize, затем формат и качество, затем специальные параметры. Не пытайтесь механически сопоставить quality=75 разных кодеков: одинаковые числа не означают одинаковую визуальную потерю.
Различие оригинального CLI и форков
После прекращения активной поддержки оригинального npm-пакета появились форки, которые возвращают CLI, добавляют новые способы установки, ограничение concurrency, исправления для новых Node и другие функции. Это полезная экосистема, но в статье о Squoosh CLI важно не переносить возможности форка в оригинальный @squoosh/cli.
Если вы видите инструкцию с флагом, которого нет в squoosh-cli --help, сначала проверьте имя пакета. У форка может быть похожая команда squoosh-cli, но иная реализация. То же относится к Homebrew/Scoop-бинарникам, флагу --in-place, настройкам максимального числа файлов и современным исправлениям WASM-loader.
Для воспроизводимости записывайте не только название «Squoosh CLI», но и точный пакет. В данном материале под программой понимается оригинальный пакет @squoosh/cli из проекта GoogleChromeLabs Squoosh, а форки упоминаются только как контекст совместимости.
Безопасность работы с исходниками
Хотя CLI обрабатывает данные локально и не требует отправлять фотографии на внешний сервис, главный риск — случайная перезапись или потеря качества. Поэтому исходники должны быть неизменяемыми. Храните мастер-файлы отдельно или под системой резервного копирования, а все результаты считайте производными.
Перед массовым запуском проверьте, куда пишет -d, и используйте суффикс. Не запускайте экспериментальный профиль на единственной папке фотографий. Даже если кодек не перезапишет исходное расширение, скрипт вокруг него может удалить старые файлы после успеха.
В CI запускайте программу с минимальными правами. Ей нужна запись только в каталог артефактов. Нет причины давать процессу доступ к секретам или всей файловой системе контейнера. Это стандартная гигиена для любых инструментов обработки ассетов.
Частые вопросы
Можно ли запускать Squoosh CLI без глобальной установки?
Да. Используется npx @squoosh/cli. Но для стабильного production-сценария лучше не полагаться на плавающую последнюю версию: фиксируйте пакет и lock-файл или используйте контейнер.
Можно ли обработать несколько файлов?
Да, команда принимает <files...> и использует worker pool. Список можно сформировать оболочкой. На больших партиях следите за памятью и не позволяйте glob захватывать каталоги.
Можно ли получить WebP и AVIF одновременно?
Да, укажите оба энкодера. Получатся два выходных файла для каждого входа. Учитывайте рост времени и памяти.
Есть ли предпросмотр?
Нет. Это консольная программа. Для визуального контроля открывайте результаты внешним просмотрщиком или создавайте тестовую страницу.
Сохраняются ли EXIF и ICC?
Не рассчитывайте на сохранение полного набора метаданных. Для архивов храните оригиналы и отдельно проверяйте нужные профили/теги.
Почему команда из веб-версии может не работать?
Схемы параметров UI и CLI в старых выпусках не всегда совпадали, а кавычки могли изменяться оболочкой. Упростите объект и сверяйте ключи конкретного CLI.
Почему AVIF не реагирует на quality?
В оригинальной схеме AVIF основным параметром был cqLevel. Универсальный quality не был эквивалентом WebP/JPEG.
Стоит ли использовать автооптимизацию?
Она полезна для эксперимента и подбора, но делает несколько кодирований и в старых версиях имела спорные случаи. Для массового CI часто лучше фиксированный проверенный профиль.
Итоговый рабочий порядок
Для нового набора изображений сначала определите назначение и конечные размеры. Затем возьмите несколько типичных исходников, запустите Squoosh CLI в отдельный каталог с пустой конфигурацией кодека и убедитесь, что среда работает. Добавьте resize, после него параметры качества. Только после визуальной проверки переносите профиль на всю партию.
При пакетном запуске ограничивайте объём группы, если изображения крупные, и следите за памятью. Используйте -d и -s, чтобы не путать исходники с производными. На Windows проверяйте поведение glob в вашей оболочке. При ошибках конфигурации сокращайте объект до минимума. При ошибках WASM сначала воспроизводите на одном файле и сверяйте Node.js.
Squoosh CLI наиболее полезен как небольшой, детерминированный этап подготовки веб-изображений: один и тот же набор команд можно хранить рядом с проектом, запускать локально или в изолированном CI и получать предсказуемую структуру выходных файлов. Его ограничения — отсутствие визуального контроля, узкий набор операций и зависимость оригинальной версии от старой среды — нужно учитывать заранее, а не пытаться компенсировать длинными случайными параметрами.
Потоки вывода, коды завершения и журналы
В ручной работе человек видит прогресс и сразу замечает красную строку ошибки. В автоматизации этого недостаточно: вызывающая система должна проверять код завершения процесса. Не стройте pipeline только на поиске слова Squoosh results в тексте. Лог может быть частичным, worker может напечатать исключение, а процесс — остаться висеть. Скрипт должен иметь тайм-аут, считывать код завершения и отдельно проверять артефакты.
Для локального Bash-сценария полезно включить остановку при ошибке оболочки и перенаправить журнал в файл. Но помните, что stdout и stderr могут перемешиваться из-за параллельных workers. Если нужен машинно-читаемый отчёт, надёжнее после выполнения самостоятельно пройти по каталогу результата и собрать размеры, имена и MIME-типы. Squoosh CLI не обещает стабильный JSON-формат лога.
В CI сохраняйте лог не как единственный артефакт, а вместе со списком входов и версией окружения. Если через полгода один файл начнёт падать, информация «использовали Node 16 и @squoosh/cli 0.7.3» гораздо ценнее, чем только стек исключения. Для старого программного пакета окружение фактически является частью конфигурации.
Если процесс склонен зависать после исключения, добавьте внешний тайм-аут. Значение выбирают по нормальной длительности вашей партии с запасом. Тайм-аут не лечит ошибку, но предотвращает бесконечно занятый runner и делает сбой наблюдаемым.
Коллизии имён и повторные запуски
При массовом преобразовании проблема имён возникает раньше, чем кажется. Два источника из разных каталогов могут иметь одинаковое базовое имя cover.jpg. Если все результаты направить в один output, один файл может конфликтовать с другим. Оригинальный CLI не является системой сохранения иерархии каталогов, поэтому структуру нужно проектировать вокруг него.
Есть три безопасных подхода. Первый — обрабатывать каждый исходный каталог отдельно и задавать свой -d. Второй — формировать уникальные имена до запуска, например включать идентификатор сущности в basename. Третий — внешний скрипт, который создаёт зеркальные каталоги и запускает CLI для каждой группы. Не рассчитывайте, что суффикс решит коллизию, если базовые имена полностью одинаковы.
Повторный запуск поверх существующего результата тоже должен быть осознанным. Если параметры изменились, старые файлы могут остаться рядом с новыми и больше не соответствовать текущему профилю. В CI проще очищать каталог производных ресурсов перед полной сборкой или генерировать во временную директорию и заменять целевую только после успеха.
Для локального инкрементального процесса можно сравнивать время изменения и хеш исходника. Но добавьте к ключу кэша параметры: изменение quality или width должно принудительно пересоздать файл, даже если мастер не менялся.
Прозрачность и альфа-канал
PNG, WebP и AVIF могут содержать прозрачность, JPEG — нет. При выборе формата это важнее средней степени сжатия. Если логотип имеет прозрачные края, преобразование в MozJPEG без предварительного сведения на фон изменит смысл ресурса. На светлом фоне дефект может быть незаметен, а на тёмном появятся нежелательные края.
У WebP в объекте энкодера есть параметры, относящиеся к alpha compression и alpha quality. Их стоит трогать только после проверки. Слишком низкое качество альфа-канала проявляется не как обычные JPEG-блоки внутри объекта, а как грязная граница, ступеньки или ореол вокруг полупрозрачных элементов. Для UI это особенно заметно.
Resize полупрозрачного изображения связан с premultiply. При корректном предварительном умножении цвета на альфу смешивание краевых пикселей даёт меньше цветных ореолов. Поэтому значение premultiply в препроцессоре не является косметическим флагом. Если его менять, сравнивайте края на контрастных подложках.
Для иконок с ограниченной палитрой PNG после quant и OxiPNG часто остаётся рациональным вариантом. Для больших полупрозрачных иллюстраций WebP или AVIF могут дать меньший размер, но сначала проверьте, что все целевые клиенты корректно отображают альфу.
Скриншоты интерфейсов и мелкий текст
Скриншоты отличаются от фотографий резкими границами и большим числом однотонных областей. Агрессивный lossy JPEG может создавать ringing вокруг букв и цветные ореолы около контрастных линий. Поэтому профиль, который хорошо выглядит на пейзаже при quality 70, может быть неприемлем для документации или интерфейса.
Для скриншотов сравните PNG/OxiPNG, WebP lossless и умеренный lossy WebP. Quant может дать сильный выигрыш, если интерфейс использует ограниченную палитру, но способен повредить градиенты, тени и полупрозрачность. Проверяйте мелкий текст на 100% масштабе.
Если скриншот вставляется в статью шириной 900 пикселей, нет смысла хранить 4K-копию, если читателю не нужен zoom. Resize до фактической ширины с хорошим фильтром часто уменьшает файл сильнее, чем смена PNG на экзотический формат. Сначала оптимизируйте геометрию, затем кодек.
Для технической документации особенно важно не искажать значения, подписи и тонкие графики. Автооптимизатор по перцептивной метрике может считать небольшое изменение допустимым, а оно затронет символ. Поэтому для таких ресурсов лучше консервативные профили и ручной golden set.
Фотографии с шумом, зерном и мелкой фактурой
Шумные ночные снимки и фотографии с плёночным зерном — трудные источники для любого lossy-кодека. Энкодер тратит много битов на высокочастотную текстуру либо сглаживает её. Если задача — веб-представление, иногда умеренное подавление шума до кодирования даёт лучший визуальный результат при меньшем размере, но Squoosh CLI не содержит полноценного denoise-препроцессора для произвольной фотографии.
Не пытайтесь компенсировать шум только снижением качества. Это превращает мелкое зерно в крупные блоки или размазанные пятна. Лучше подготовить мастер в фоторедакторе, затем применять CLI уже к финальному изображению. Squoosh CLI — последняя стадия доставки, а не RAW-процессор.
Листва, волосы, вода и ткань также требуют осторожности. На них различия между кодеками видны сильнее, чем на гладком фоне. Если для проекта важен художественный вид, включите такие кадры в golden set, а не оценивайте качество по одному предметному фото на белом фоне.
Responsive images: несколько размеров без путаницы
Для современного сайта одной картинки часто недостаточно. Браузеру полезно предложить несколько ширин, чтобы мобильное устройство не загружало десктопный ресурс. Squoosh CLI способен создать каждую ширину, но матрицу нужно организовать внешне.
Удобная схема имён: hero-640.webp, hero-1280.webp, hero-1920.webp и такие же AVIF при необходимости. Суффикс CLI помогает сформировать это имя. Для каждого размера запускается отдельная команда resize. Затем HTML srcset или CMS связывает ширины с ресурсами.
Не генерируйте десяток почти одинаковых размеров. Каждая производная занимает место в хранилище и CDN, а выигрыш между 1200 и 1280 может быть минимальным. Обычно выбирают несколько ступеней, соответствующих макету. Параметры должны исходить из реальных breakpoints, а не из способности инструмента произвести сколько угодно файлов.
Если используются AVIF и WebP одновременно, количество артефактов удваивается. В таком случае особенно полезен генератор манифеста: внешний скрипт после Squoosh CLI записывает, какие файлы созданы и какой у них размер. Сам CLI такого manifest-файла не создаёт.
Выбор качества по бюджету страницы
Вместо вопроса «какое качество лучше» полезно задать бюджет. Например, hero не должен превышать определённый диапазон при типичном содержимом, а карточка должна быть значительно меньше. Это не жёсткий лимит для каждого кадра, а сигнал для проверки аномалий.
Сначала установите минимально приемлемое визуальное качество на representative set. Затем посмотрите медианный и максимальный размеры. Если отдельный кадр выбивается, возможно, он содержит шум, избыточную геометрию или альфа-канал. Не снижайте качество всего проекта ради одного сложного изображения.
Автооптимизатор Butteraugli формально идёт от визуальной дистанции, а не от заданного байтового размера. Поэтому он не решает задачу «любой файл не больше 150 КБ». Для строгого размера потребуется внешний цикл, который меняет качество и сравнивает файл, либо другой инструмент с target-size режимом.
При строгом бюджете учитывайте, что размер зависит от содержания. Один и тот же quality=75 даст разные числа на небе и густой листве. Профиль качества обеспечивает приблизительно сходную степень потерь, но не фиксированное количество байт.
Контроль целостности после массовой обработки
Хороший пакетный процесс завершается верификацией. Минимум — число выходных файлов должно соответствовать ожидаемому числу преобразований. Если для каждого входа запрошены WebP и AVIF, ожидается два результата, если имена не конфликтуют.
Следующая проверка — декодируемость. Независимый инструмент должен открыть каждый выходной файл и сообщить размеры изображения. Это ловит нулевые, обрезанные или ошибочно названные файлы. Для веба полезно также проверять, что ширина/высота соответствуют профилю.
Для критичных пайплайнов можно вычислять perceptual hash и выявлять полностью чёрные или неожиданные одинаковые результаты. Но автоматические метрики не заменяют визуальный контроль при изменении настроек. Они хороши для обнаружения грубых отказов.
Если партия прерывается, не считайте уже созданные файлы автоматически валидными только потому, что они существуют. Кодируйте во временную директорию, проверьте набор, затем публикуйте. Такой двухфазный подход предотвращает попадание половины старых и половины новых ресурсов на сайт.
Работа в Docker
Контейнер — практичный способ удержать совместимый Node.js, не затрагивая современную систему. В Dockerfile фиксируется базовый образ, версия пакета и рабочий каталог. Исходники монтируются read-only, каталог результата — с записью. Это также упрощает запуск одинаковой команды на Linux, macOS и CI.
Но не используйте контейнер как повод загружать случайный сторонний образ. Для воспроизводимости лучше собрать собственный минимальный образ из известной версии Node и npm-пакета. Тогда понятно, какой код выполняется и какие зависимости входят в слой.
Следите за владельцем файлов. Если контейнер работает от root, результаты на Linux-хосте получат root-владельца. Создайте внутри пользователя с подходящим UID/GID или после запуска исправляйте права. Это не влияет на качество изображения, но влияет на реальную пригодность процесса для команды.
Ограничение памяти контейнера полезно как ранний сигнал. Если CLI стабильно выходит за 2–4 ГБ на вашей партии, вместо бесконечного увеличения лимита стоит уменьшить размер группы или поменять инструмент. Память — часть стоимости pipeline.
Портируемые сценарии для разных оболочек
Команда, записанная для Bash, не является автоматически переносимой в PowerShell. Различаются кавычки, wildcard и экранирование. Если команда должна работать на трёх ОС, лучше написать маленький Node-скрипт, который формирует массив аргументов и запускает CLI без shell. Тогда JSON передаётся как строка напрямую, а список файлов формируется через API файловой системы.
В npm scripts оболочка тоже зависит от платформы. Простая строка с *.jpg может сработать на Linux runner и провалиться на Windows. Кроссплатформенный проект должен тестировать именно ту оболочку, которую использует CI, либо исключить glob из командной строки.
Если Bash — официальная часть проекта, это нормально: зафиксируйте требование в документации и запускайте через контейнер. Проблема начинается не с платформенной зависимости, а с неявной платформенной зависимости, о которой команда узнаёт только при аварии сборки.
Почему не стоит копировать длинную команду из старого Squoosh
В ранних версиях веб-интерфейс мог предлагать действие Copy npx command и формировать объект со всеми параметрами энкодера. Это выглядело удобно, но имело побочный эффект: команда жёстко привязывалась к схеме конкретной версии. Если один ключ переименован или UI и CLI расходятся, длинная команда перестаёт работать.
Минималистичный профиль устойчивее. Если вам нужен только quality 75, укажите только quality 75. Значения по умолчанию берутся из установленного кодека. Исключение — когда абсолютная воспроизводимость важнее переносимости и вы намеренно фиксируете весь объект вместе с версией пакета.
После копирования команды всегда удаляйте параметры, смысл которых вы не понимаете, только если предварительно сравнили результат. Некоторые значения влияют на цветность, альфу и скорость. Цель не «сделать строку короче любой ценой», а сохранить осознанные настройки.
Профили для разных типов контента
| Тип | Стартовая стратегия | Что проверять |
|---|---|---|
| Фотография | Resize + MozJPEG/WebP, отдельно AVIF | Кожа, листва, шум, градиенты |
| Скриншот | PNG/OxiPNG или WebP lossless | Текст, тонкие линии, тени |
| Иконка | Quant + OxiPNG, если палитра ограничена | Прозрачные края, фирменные цвета |
| Большой hero | Сначала resize до реальной ширины | Вес, визуальные артефакты в 100% |
| Изображение с альфой | PNG/WebP/AVIF, не JPEG | Ореолы на тёмном и светлом фоне |
| Архивный мастер | Не заменять производной CLI | Метаданные, профиль цвета, исходные пиксели |
Таблица задаёт направление, а не готовый пресет. Squoosh CLI не анализирует семантику и не выбирает формат автоматически. Один PNG может быть скриншотом, другой — фотографией с прозрачностью, третий — пиксельной иконкой. Расширение исходника не определяет правильный выход.
Когда результат стал больше исходника
Это нормальная ситуация для части файлов. Уже оптимизированный JPEG может стать больше после перекодирования при высоком качестве. Маленький PNG с несколькими цветами может быть компактнее WebP. AVIF имеет служебные накладные данные, заметные на очень маленьких изображениях.
Не решайте проблему автоматическим снижением качества до тех пор, пока новый формат не станет меньше. У вас может появиться худший визуально файл с незначительным выигрышем. Логичнее сравнить и оставить исходный ресурс, если он уже эффективен и совместим.
В batch-скрипте можно после кодирования сравнить размеры и удалять производную, если она больше и формат не требуется по другой причине. Например, WebP может быть нужен как стандартизованный формат CDN даже при небольшом проигрыше в байтах. Тогда размер — не единственный критерий.
Отладка одного проблемного файла
Создайте отдельную пустую папку и скопируйте туда один проблемный источник. Запустите squoosh-cli --mozjpeg '{}' -d out file.jpg или другой простой энкодер. Если даже это падает, проверьте декодирование. Если работает — проблема в конкретном препроцессоре или параметре.
Далее тестируйте --resize отдельно с базовым энкодером, затем quant, затем rotate. После этого возвращайте целевой кодек. В AVIF сначала пустой объект, затем cqLevel. Такой порядок локализует проблему за несколько запусков.
Не тестируйте на оригинале единственного файла. Даже диагностический процесс должен писать в отдельный каталог. После каждого шага открывайте результат, потому что отсутствие исключения не гарантирует правильный цвет, ориентацию и геометрию.
Подготовка к отказу и восстановление
Batch-процесс должен быть повторяемым. Если он упал на 73-м файле из 100, у вас должно быть два допустимых варианта: очистить временный каталог и запустить заново или продолжить по списку неполученных результатов. Не смешивайте ручное «доделывание» с автоматическим набором — это создаёт неотслеживаемые параметры.
Храните список исходников и конфигурацию рядом с логом. Для разовой миграции можно записать manifest до начала. После выполнения manifest сравнивается с каталогом результатов. Так легко увидеть пропуски.
Если процесс сломался после обновления среды, откатите среду, а не параметры изображений. Сначала подтвердите, что прежняя комбинация Node/CLI всё ещё выдаёт ожидаемый результат. Затем отдельно планируйте миграцию. Иначе можно одновременно менять runtime и качество и потерять возможность понять причину различий.
Практический чек-лист перед массовым запуском
- Оригиналы сохранены отдельно и не будут перезаписаны.
- Версии Node.js и
@squoosh/cliзафиксированы. squoosh-cli --helpсоответствует ожидаемому набору флагов.- Команда проверена на нескольких разных изображениях.
- Каталог вывода отдельный и доступен для записи.
- Glob раскрывается выбранной оболочкой только в обычные файлы.
- Resize не искажает пропорции контрольных кадров.
- Прозрачность сохраняется там, где она нужна.
- Качество проверено визуально, а не только по размеру.
- Памяти достаточно для выбранного размера партии.
- Скрипт проверяет код завершения и число результатов.
- При ошибке можно безопасно повторить весь процесс.
Если все пункты выполняются, Squoosh CLI работает предсказуемо как узкий инструмент конвейера. Если нет, сначала устраните операционный риск, а уже затем оптимизируйте проценты сжатия. Для массовой обработки надёжность и воспроизводимость важнее единичного рекордно маленького файла.
Проверка параметров после обновления окружения
Даже если команда годами хранится в репозитории, её результат нельзя считать вечным. Меняется Node.js, системная архитектура, версия npm, контейнерная база и поведение зависимостей. После любого такого изменения повторно прогоните golden set и сравните выход с эталоном. В первую очередь смотрите на декодирование, ориентацию, цвет, размеры и факт создания всех форматов.
Если отличаются только байты при визуально одинаковом результате, выясните, не сменилась ли версия кодека. Если заметно изменился размер, проверьте значения по умолчанию и то, что ваш минимальный объект конфигурации по-прежнему означает прежний профиль. Если изменился внешний вид, останавливайте публикацию до локализации причины.
Для старого Squoosh CLI особенно опасно «починить» несовместимость случайным обновлением форка под тем же командным именем. Скрипт продолжит выполняться, но это уже будет другое программное окружение. В manifest или lock-файле должно быть видно точное имя пакета.
Как читать процент в консольном результате
В строках результата Squoosh CLI рядом с размером выходного файла показывал процент относительно исходника. Например, 20% означает, что новый файл занимает примерно пятую часть исходного размера, а не что «сэкономлено 20%». Поэтому при чтении журнала различайте долю итогового размера и процент экономии. Если результат равен 20% исходного, уменьшение составляет около 80%.
Эта цифра не говорит о качестве и не учитывает изменение разрешения. Файл после resize до четверти площади закономерно станет намного меньше, даже если энкодер настроен мягко. При сравнении кодеков используйте одинаковую геометрию, иначе вы измеряете сразу две операции.
Для отчёта проекта полезнее хранить исходный и итоговый размер в байтах, формат, ширину/высоту и профиль. Тогда экономию можно пересчитать однозначно, а журнал CLI остаётся вспомогательной диагностикой.
Отдельные профили для разработки и публикации
Во время разработки нет необходимости каждый раз запускать самый тяжёлый AVIF-профиль. Можно держать быстрый локальный режим с WebP или MozJPEG и production-режим, который дополнительно генерирует AVIF. Важно, чтобы геометрия и структура имён оставались совместимыми, иначе разработчик увидит другую разметку, чем реальный сайт.
Production-профиль запускайте в детерминированной среде и сохраняйте результаты в артефакты сборки. Если изображения редко меняются, допускается предварительная генерация и коммит производных файлов, но тогда нужен процесс, который не позволяет забыть пересобрать их после изменения мастера.
Разделение профилей также помогает диагностике: если быстрый WebP проходит, а production AVIF падает, ясно, что проблема находится в тяжёлом энкодере или его окружении, а не в базовом чтении исходников.
Что считать успешной настройкой Squoosh CLI
Успех — не минимальный размер одного файла. Рабочая настройка должна давать приемлемое качество на разных типах изображений, завершаться без ручного вмешательства, укладываться в доступную память, воспроизводиться на другой машине проекта и не разрушать исходники. Если ради нескольких процентов экономии приходится поддерживать хрупкую команду из десятков неясных флагов, профиль стоит упростить.
Для небольшого сайта достаточно одного-двух профилей, проверенных на representative set. Для большой медиатеки потребуется внешняя обвязка: очередь, кэш, manifest, валидация и контролируемая параллельность. Squoosh CLI может быть кодирующим звеном такой схемы, но не заменяет её целиком.
Именно поэтому программу лучше воспринимать как специализированный консольный инструмент: она хорошо выполняет предсказуемые преобразования, когда пользователь заранее определил формат, размеры и параметры, а ответственность за выбор файлов, публикацию, сохранность мастеров и контроль качества остаётся у окружающего рабочего процесса.
