Зупиніть стиснення зображень у WordPress на рівні 82%
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 є помітно руйнівним: ви отримуєте «москітний» шум, що повзає навколо кожної літери, та смугастість (banding) на плавних градієнтах.
Щоб це змінити, додайте один фільтр і перегенеруйте мініатюри. Щоб виправити конкретно скріншоти, кращою відповіддю зазвичай є взагалі не віддавати 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 на кожному проході. Сам оригінально завантажений файл залишається недоторканим, якщо він менший за поріг великого зображення (2560px по довшому краю). Якщо ж він перевищує цей поріг, 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 і залишиться на 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, якщо ваші зображення менші за 2560px — цей шлях для них ніколи не виконується. Якщо ж ви дійсно в нього потрапляєте і хочете, щоб віддавався недоторканий оригінал, це окреме налаштування; див. вимкнення масштабованих зображень.
Досі не виходить?
Якщо конкретний розмір усе ще виглядає неправильно після перегенерації, з’ясуйте, який саме файл сторінка насправді віддає — відкрийте зображення в новій вкладці й перевірте, чи закінчується назва файлу суфіксом розміру (-1024x768.jpg) або -scaled.jpg. Інспектор розмірів зображень показує кожну похідну, яку WordPress генерує з одного завантаження, тож ви можете точно побачити, який розмір ваш srcset віддає браузеру, і припинити налагоджувати не той файл.