Оптимизация изображений в Gulp под Google PageSpeed Insights
Мне очень нравится использовать Gulp для сборки проектов, он быстр, легок, поддается прекрасной автоматизации. Но есть небольшой изъян в том решении, которое мною используется, а именно, оптимизированные стандартным imagemin картинки не проходят проверку в Google PageSpeed Insights в виду недостаточной оптимизации. Решил, что пора уже исправить это досадное недоразумение.
Любой, кто использовал стандартный gulp-imagemin для оптимизации картинок, как это делается рассказывал когда описывал основы Gulp, обращал внимание, что картинки жмутся не оптимальным образом. Проверить это достаточно просто, возьмем мой последний пост и отправим его в Google PageSpeed Insights. Как видим Google сообщает нам, что "Оптимизируйте следующие изображения, чтобы уменьшить их размер на 12,7 КБ (42 %)".
Перейдя на страницу помощи мы можем найти кое что полезное, например погуглить опции для jpegtran или поискать реализацию jpegoptim для Gulp. Забегая немного вперед, нам пригодится только jpegoptim. У встроенного в imagemin пакета imagemin-jpegtran практически нет дополнительных опций для оптимизации. В общем, после поисков и экспериментов было принято решение проверить две гипотезы.
Для проведения тестирования мы будем использовать тестовый стенд (тестовая программа), за основу которого был взят пример из прошлой статьи об основах Gulp. Для тестирования были взяты картинки разных форматов и размеров. После чего было сделано поэтапное сжатие этих картинок различными средствами оптимизации картинок с записью результатов и проверкой их в Google PageSpeed Insights. Стенд доступен по ссылке. Оригиналы файлов доступны в архиве source.rar. Пожатые файлы доступны в архиве optimized.rar.
PNG можно сжимать эффективнее
Проблема с PNG в том, что Google PageSpeed Insights на него не ругается. Я загружал ужасно большие фотографии с наборами мета-данных и PageSpeed Insights ни разу даже не пискнул.
Поэтому решил поэкспериментировать с PNG без обратной связи от гугла. Да, штатные средства сжимают PNG формат не очень хорошо.
Небольшие пояснения по таблице:
Название файла - это исходный файл, который жмется и который можно найти в архиве source.rar.
Средство оптимизации и опции - показывает каким именно средством производилась оптимизация и какие при этом использовались параметры. Параметры качества в 60 взяты из Photoshop, который считает, что это нормальное качество (High) картинки при обработке.
Saved Kb - количество байт/килобайт/мегабайт, которые удалось съэкономить благодаря оптимизации.
Saved % - тоже самое, только в процентном соотношении к размеру файла.
Google PageSpeed Insights - предупреждает ли сервис PageSpeed Insights, что данное изображение необходимо подвергнуть повторной оптимизации или нет.
Название файла | Средство оптимизации и опции вызова | Saved Kb | Saved % | Google PageSpeed Insights |
Pinguino-Linux.png | imagemin.optipng({optimizationLevel: 5}) | 74 B | 0.1% | не предупреждает |
Pinguino-Linux.png | pngquant() | 47.7 kB | 47.9% | не предупреждает |
Pinguino-Linux.png | pngquant({quality: 60, speed: 5}) | 73 kB | 73.3% | не предупреждает |
Название файла | Средство оптимизации и опции вызова | Saved Kb | Saved % | Google PageSpeed Insights |
linux-2025130.png | imagemin.optipng({optimizationLevel: 5}) | 18.2 kB | 16.1% | не предупреждает |
linux-2025130.png | pngquant() | 62.6 kB | 55.5% | не предупреждает |
linux-2025130.png | pngquant({quality: 60, speed: 5}) | 87.1 kB | 77.2% | не предупреждает |
Как видно из таблицы, даже без опций дополнение gulp-pngquant жмет гораздо лучше. Буду использовать его.
JPEG можно сжимать эффективнее
После продолжительных поисков было найдено 3 кандидата, которые должны были расширить базовые возможности imagemin. Это imagemin-jpeg-recompress, imagemin-jpegoptim, imagemin-mozjpeg. Не вдаваясь в особые разглагольствования, выкладываю результаты тестов:
Название файла | Средство оптимизации и опции вызова | Saved Kb | Saved % | Google PageSpeed Insights |
code-1839406.jpg | imagemin.jpegtran({progressive: true}) | 19.2 kB | 12% | Сжатие страницы уменьшит ее размер на 31,2 КБ (23 %). |
code-1839406.jpg | jpegoptim() | 7.83 kB | 4.9% | Сжатие страницы уменьшит ее размер на 42,3 КБ (29 %). |
code-1839406.jpg | jpegoptim({progressive: true, max: 60, stripAll: true}) | 93.3 kB | 58.5% | не предупреждает |
code-1839406.jpg | recompress() | 58.2 kB | 36.4% | не предупреждает |
code-1839406.jpg | recompress({quality: "medium", method: "smallfry", loops: 5, progressive: true, strip: true}) | 87.7 kB | 55% | не предупреждает |
code-1839406.jpg | mozjpeg() | 87.5 kB | 54.8% | не предупреждает |
code-1839406.jpg | mozjpeg({quality: 60, progressive: true, tune: "ms-ssim", smooth: 2}) | 113 kB | 70.9% | не предупреждает |
Название файла | Средство оптимизации и опции вызова | Saved Kb | Saved % | Google PageSpeed Insights |
market-839574.jpg | imagemin.jpegtran({progressive: true}) | 30.7 kB | 6.7% | Сжатие страницы уменьшит ее размер на 75,6 КБ (19 %). |
market-839574.jpg | jpegoptim() | 6.54 kB | 1.4% | Сжатие страницы уменьшит ее размер на 99,2 КБ (23 %). |
market-839574.jpg | jpegoptim({progressive: true, max: 60, stripAll: true}) | 322 kB | 69.9% | не предупреждает |
market-839574.jpg | recompress() | 164 kB | 35.6% | не предупреждает |
market-839574.jpg | recompress({quality: "medium", method: "smallfry", loops: 5, progressive: true, strip: true}) | 215 kB | 46.8% | не предупреждает |
market-839574.jpg | mozjpeg() | 286 kB | 62.3% | не предупреждает |
market-839574.jpg | mozjpeg({quality: 60, progressive: true, tune: "ms-ssim", smooth: 2}) | 357 kB | 77.6% | не предупреждает |
Название файла | Средство оптимизации и опции вызова | Saved Kb | Saved % | Google PageSpeed Insights |
red-rose-2602048.jpg | imagemin.jpegtran({progressive: true}) | 29.8 kB | 5.1% | уменьшит ее размер на 113,8 КБ (22 %). |
red-rose-2602048.jpg | jpegoptim() | 210 B | 0% | уменьшит ее размер на 142,7 КБ (26 %). |
red-rose-2602048.jpg | jpegoptim({progressive: true, max: 60, stripAll: true}) | 411 kB | 70.3% | не предупреждает |
red-rose-2602048.jpg | recompress() | 210 kB | 35.9% | не предупреждает |
red-rose-2602048.jpg | recompress({quality: "medium", method: "smallfry", loops: 5, progressive: true, strip: true}) | 275 kB | 47.1% | не предупреждает |
red-rose-2602048.jpg | mozjpeg() | 367 kB | 62.9% | не предупреждает |
red-rose-2602048.jpg | mozjpeg({quality: 60, progressive: true, tune: "ms-ssim", smooth: 2}) | 457 kB | 78.3% | не предупреждает |
Как видно, лучше всех себя показывает mozjpeg даже без передачи каких-либо параметров. После обработки изображений никаких претензий со стороны Google PageSpeed Insights нет. При этом хочу обратить особое внимание, что несмотря на существенную степень сжатия качество изображений не пострадало, по крайней мере визуально изображения выглядят идентично с оригиналом. Посмотреть результаты и сравнить качество сжатия можно в архиве optimized.rar.
В конце хотел дополнить, что тестирование проводилось не только с теми картинками, которые доступны в архиве. В ходе тестирования заметил, что картинки больше 2000 пикселей по ширине и больше нормально не жмутся любыми перечисленными средствами Gulp согласно Google PageSpeed Insights. Для таких картинок надо искать более серьезные решения, включая те средства, которыми пользуются в самом Google :)
UPDATE: в ходе дальнейших экспериментов с JPEG форматом выяснилось несколько вещей:
imagemin-jpeg-recompress с методом компрессии smallfry часто дает ошибку, как-то связано с размерами изображения, но библиотека jpeg-archive давно не исправляется, поэтому от этого jpeg-recompress отказался.
imagemin-mozjpeg все таки визуально сильно портит качество на небольших и особенно маленьких изображениях, поэтому от него так же отказался.
Есть какое-то решение все таки, чтоб наконец отстал от картинок?
Если он ругается на картинки, то в самом низу предлагает ссылку на скачивание оптимально оптимизированных с его точки зрения ресурсов. Посмотрите ближе к низу страницы: «Скачать оптимизированные изображения, ресурсы JavaScript и CSS для этой страницы» :)
minJpg({progressive: true, max: 85, stripAll: true}),
Можно еще использовать комбо из jpegoptim и mozjpeg, правда выигрыш в среднем 2кб.