Блог/Оптимизация изображений в Gulp

Оптимизация изображений в Gulp под Google PageSpeed Insights

Автор: Кудашев Сергей

Мне очень нравится использовать Gulp для сборки проектов, он быстр, легок, поддается прекрасной автоматизации. Но есть небольшой изъян в том решении, которое мною используется, а именно, оптимизированные стандартным imagemin картинки не проходят проверку в Google PageSpeed Insights в виду недостаточной оптимизации. Решил, что пора уже исправить это досадное недоразумение.

Любой, кто использовал стандартный gulp-imagemin для оптимизации картинок, как это делается рассказывал когда описывал основы Gulp, обращал внимание, что картинки жмутся не оптимальным образом. Проверить это достаточно просто, возьмем мой последний пост и отправим его в Google PageSpeed Insights. Как видим Google сообщает нам, что "Оптимизируйте следующие изображения, чтобы уменьшить их размер на 12,7 КБ (42 %)".

Gulp и Google PageSpeed Insights наглядно

Перейдя на страницу помощи мы можем найти кое что полезное, например погуглить опции для 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 KbSaved %Google PageSpeed Insights
Pinguino-Linux.pngimagemin.optipng({optimizationLevel: 5})74 B0.1%не предупреждает
Pinguino-Linux.pngpngquant()47.7 kB47.9%не предупреждает
Pinguino-Linux.pngpngquant({quality: 60, speed: 5})73 kB73.3%не предупреждает
Название файлаСредство оптимизации и опции вызоваSaved KbSaved %Google PageSpeed Insights
linux-2025130.pngimagemin.optipng({optimizationLevel: 5})18.2 kB16.1%не предупреждает
linux-2025130.pngpngquant()62.6 kB55.5%не предупреждает
linux-2025130.pngpngquant({quality: 60, speed: 5})87.1 kB77.2%не предупреждает

Как видно из таблицы, даже без опций дополнение gulp-pngquant жмет гораздо лучше. Буду использовать его.

JPEG можно сжимать эффективнее

После продолжительных поисков было найдено 3 кандидата, которые должны были расширить базовые возможности imagemin. Это imagemin-jpeg-recompress, imagemin-jpegoptim, imagemin-mozjpeg. Не вдаваясь в особые разглагольствования, выкладываю результаты тестов:

Название файлаСредство оптимизации и опции вызоваSaved KbSaved %Google PageSpeed Insights
code-1839406.jpgimagemin.jpegtran({progressive: true})19.2 kB12%Сжатие страницы уменьшит ее размер на 31,2 КБ (23 %).
code-1839406.jpgjpegoptim()7.83 kB4.9%Сжатие страницы уменьшит ее размер на 42,3 КБ (29 %).
code-1839406.jpgjpegoptim({progressive: true, max: 60, stripAll: true})93.3 kB58.5%не предупреждает
code-1839406.jpgrecompress()58.2 kB36.4%не предупреждает
code-1839406.jpgrecompress({quality: "medium", method: "smallfry", loops: 5, progressive: true, strip: true})87.7 kB55%не предупреждает
code-1839406.jpgmozjpeg()87.5 kB54.8%не предупреждает
code-1839406.jpgmozjpeg({quality: 60, progressive: true, tune: "ms-ssim", smooth: 2})113 kB70.9%не предупреждает
Название файлаСредство оптимизации и опции вызоваSaved KbSaved %Google PageSpeed Insights
market-839574.jpgimagemin.jpegtran({progressive: true})30.7 kB6.7%Сжатие страницы уменьшит ее размер на 75,6 КБ (19 %).
market-839574.jpgjpegoptim()6.54 kB1.4%Сжатие страницы уменьшит ее размер на 99,2 КБ (23 %).
market-839574.jpgjpegoptim({progressive: true, max: 60, stripAll: true})322 kB69.9%не предупреждает
market-839574.jpgrecompress()164 kB35.6%не предупреждает
market-839574.jpgrecompress({quality: "medium", method: "smallfry", loops: 5, progressive: true, strip: true})215 kB46.8%не предупреждает
market-839574.jpgmozjpeg()286 kB62.3%не предупреждает
market-839574.jpgmozjpeg({quality: 60, progressive: true, tune: "ms-ssim", smooth: 2})357 kB77.6%не предупреждает
Название файлаСредство оптимизации и опции вызоваSaved KbSaved %Google PageSpeed Insights
red-rose-2602048.jpgimagemin.jpegtran({progressive: true})29.8 kB5.1%уменьшит ее размер на 113,8 КБ (22 %).
red-rose-2602048.jpgjpegoptim()210 B0%уменьшит ее размер на 142,7 КБ (26 %).
red-rose-2602048.jpgjpegoptim({progressive: true, max: 60, stripAll: true})411 kB70.3%не предупреждает
red-rose-2602048.jpgrecompress()210 kB35.9%не предупреждает
red-rose-2602048.jpgrecompress({quality: "medium", method: "smallfry", loops: 5, progressive: true, strip: true})275 kB47.1%не предупреждает
red-rose-2602048.jpgmozjpeg()367 kB62.9%не предупреждает
red-rose-2602048.jpgmozjpeg({quality: 60, progressive: true, tune: "ms-ssim", smooth: 2})457 kB78.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 все таки визуально сильно портит качество на небольших и особенно маленьких изображениях, поэтому от него так же отказался.

Комментарии (6)

  1. Константин08 декабря 2017, 21:58#
    Попробовал ваш код, все равно ругается…
    Есть какое-то решение все таки, чтоб наконец отстал от картинок?
    1. Кудашев Сергей10 декабря 2017, 18:54(Комментарий был изменён)#
      Да, Констанин, можно прямо из Google PageSpeed Insights скачать.

      Если он ругается на картинки, то в самом низу предлагает ссылку на скачивание оптимально оптимизированных с его точки зрения ресурсов. Посмотрите ближе к низу страницы: «Скачать оптимизированные изображения, ресурсы JavaScript и CSS для этой страницы» :)
      1. Кудашев Сергей10 декабря 2017, 19:00#
        Других решений пока не нашел. Если найду обязательно напишу :)
      2. Юрий13 января 2018, 21:40#
        Так что в итоге используете для сжатия jpg?
        1. Кудашев Сергей16 января 2018, 17:35(Комментарий был изменён)#
          В итоге использую jpegoptim:
          minJpg({progressive: true, max: 85, stripAll: true}),
        2. Фёдор10 февраля 2019, 00:17#
          Спасибо за исследование, Сергей.
          Можно еще использовать комбо из jpegoptim и mozjpeg, правда выигрыш в среднем 2кб.