Перейти к содержимому
Изображения и медиа

Как отключить сжатие изображений на 82% в WordPress

WordPress пересжимает каждый созданный им JPEG с качеством 82 по шкале 0–100. Это значение по умолчанию задано в WP_Image_Editor::get_default_quality() и применяется

Опубликовано

WordPress пересжимает каждый создаваемый им JPEG с качеством 82 по шкале от 0 до 100. Это значение по умолчанию задано в WP_Image_Editor::get_default_quality() и применяется к каждой производной, которую WordPress нарезает из вашей загрузки — thumbnail, medium, medium_large, large и любому дополнительному размеру, который регистрирует ваша тема. Для фотографий 82 — разумный компромисс между весом файла и артефактами. Но для скриншотов, снимков интерфейса, графиков, логотипов и всего, где есть чёткий текст или плоский цвет, 82 разрушает картинку заметно на глаз: вокруг каждой буквы ползёт «москитный шум», а на плавных градиентах появляется полошение.

Чтобы изменить это значение, добавьте один фильтр и пересоздайте миниатюры. А чтобы починить именно скриншоты, лучше вообще не отдавать WordPress формат JPEG.

Откуда на самом деле берётся число 82

WordPress снизил качество JPEG по умолчанию с 90 до 82 ещё в версии 4.5 (2016) ради уменьшения веса страниц. Это значение возвращает функция get_default_quality() в файле wp-includes/class-wp-image-editor.php, и оно считывается всякий раз, когда активный редактор — WP_Image_Editor_Imagick, если на хостинге установлен Imagick, иначе WP_Image_Editor_GD — записывает файл после ресайза.

Важная деталь: 82 применяется к каждому производному размеру, а не один раз. Загрузите одно изображение — и WordPress прогонит его через кодировщик несколько раз, перекодируя с качеством 82 на каждом проходе. Сам исходный загруженный файл остаётся нетронутым, если он меньше порога больших изображений (2560 px по длинной стороне). Если же он превышает этот порог, WordPress создаёт перекодированный -scaled.jpg с качеством 82 и отдаёт как «полный» размер именно его. Так что «моё изображение в полном разрешении выглядит нормально, а версия на странице — смазанной» почти всегда означает, что srcset подставляет подразмер с качеством 82 или файл -scaled.

Как изменить качество

Достаточно подключиться к одному фильтру. wp_editor_set_quality — современный, канонический вариант: он срабатывает для JPEG и WebP и получает MIME-тип, так что можно ветвить логику:

add_filter( 'wp_editor_set_quality', function ( $quality, $mime_type ) {
    if ( 'image/jpeg' === $mime_type ) {
        return 92; // up from 82
    }
    return $quality;
}, 10, 2 );

Поместите этот код в небольшой mu-plugin (wp-content/mu-plugins/) или в плагин, привязанный к сайту. functions.php тоже подойдёт, но тогда вы потеряете настройку в момент смены темы.

Вам также встретится рекомендация использовать более старый фильтр jpeg_quality. Он по-прежнему срабатывает (WordPress применяет его сразу после wp_editor_set_quality, только для JPEG), но нет причин подключать оба — wp_editor_set_quality покрывает всё, что делал старый, и даже больше.

О чём все забывают: этот фильтр влияет только на изображения, закодированные после того, как он стал активным. Каждая миниатюра, уже лежащая в wp-content/uploads, была записана с качеством 82 и такой и останется. Пересоздайте их:

wp media regenerate --yes

Если вы не работаете с WP-CLI, плагин Regenerate Thumbnails делает то же самое через админку.

Прежде чем окончательно выбрать число, стоит увидеть, что то или иное качество делает именно с вашим изображением, а не гадать. Наш инструмент качества JPEG для WordPress перекодирует образец прямо в браузере на каждом уровне качества, чтобы вы могли наблюдать, как проявляются артефакты — он делает разницу между 82, 90 и 100 очевидной на скриншоте так, как число в конфиге никогда не покажет.

Более правильное решение для скриншотов и плоской графики

Повышение числа качества JPEG лечит симптом. Настоящая проблема со скриншотами в том, что JPEG — неподходящий для них кодек. DCT-сжатие в JPEG заточено под фотографические градиенты; оно разваливается на резких границах чёрного по белому в тексте и элементах интерфейса — именно поэтому качество 82 выглядит на скриншоте настолько хуже, чем на фотографии пляжа.

Загружайте вместо этого PNG. WordPress сохраняет подразмеры PNG как PNG, а PNG — формат без потерь: фильтр качества его не трогает, поэтому артефактов нет ни на одном размере, только чистое ресемплирование. Для скриншота хорошо оптимизированный PNG зачастую меньше, чем JPEG высокого качества того же изображения, потому что плоский цвет отлично сжимается в PNG и ужасно в JPEG.

Если вам нужны файлы поменьше, как у форматов с потерями, но без повреждения границ, свойственного JPEG, то WebP — золотая середина, но его качеством вы по-прежнему управляете через тот же фильтр wp_editor_set_quality, показанный выше, ветвясь на image/webp.

Чего делать не стоит

Не выставляйте качество 100 глобально. Это самый залайканный ответ в половине форумных тредов, и он неверен. JPEG с качеством 100 не является форматом без потерь — он всё равно квантует, — зато раздувает каждую фотографию на сайте в разы без видимого выигрыша, ухудшая LCP и Core Web Vitals. Повышайте число для того формата, которому это нужно, или меняйте формат для графики — не глушите сжатие по всему сайту.

Не редактируйте class-wp-image-editor.php. Изменение возвращаемого значения get_default_quality() в ядре работает ровно до следующего wp core update, который молча его перезапишет. Используйте фильтр.

Не отключайте размеры изображений, чтобы «избежать сжатия». Отключение генерации миниатюр не останавливает перекодирование — оно ломает адаптивный srcset, из-за чего браузеры на телефонах скачивают изображение в полном размере. Другая проблема, а результат хуже.

Не думайте, что повторная загрузка чинит существующие изображения. Если вы задали фильтр, но пропустили шаг пересоздания, каждая старая производная по-прежнему имеет качество 82. Фильтр работает только на будущее.

Не вините файл -scaled, если ваши изображения меньше 2560 px — для них этот путь вообще не выполняется. Если же вы в него попадаете и хотите, чтобы отдавался нетронутый оригинал, это отдельная настройка; см. отключение масштабированных изображений.

Всё ещё не получается?

Если конкретный размер после пересоздания по-прежнему выглядит неправильно, проверьте, какой файл страница фактически отдаёт — откройте изображение в новой вкладке и посмотрите, заканчивается ли имя файла суффиксом с размерами (-1024x768.jpg) или на -scaled.jpg. Инспектор размеров изображений показывает каждую производную, которую WordPress создаёт из одной загрузки, так что вы увидите, какой именно размер ваш srcset подставляет браузеру, и перестанете отлаживать не тот файл.