Drupal: Оптимизация сжатия и загрузки изображений

Простой способ оптимизировать размер изображений на сайте, при этом, при меньшей потере качества. Способ, который рекомендует Google и, соответственно, использует для проверки сжатия картинок в своих иснтрументах типа Google PageSpeed Tools, Test My Site.

30.03.2017
34 комментария
6 мин.

Скорее всего, вы пользуетесь Google PageSpeed Tools или Test My Site и если вы ничего не тюните, он будет ругаться на размер картинок. Причем порой ругается на картинок 20, и типа, пережми, сохрани 19кб! Полное безумие. Уменьшай, не уменьшай качество сжатия в Drupal, он будет ругаться и дальше, пока ты не уменьшишь качество по шкале шакалов до 5+, он всё будет ныть что не так, и то не факт что спасет. Такие проверки делают, наверное, вообще все тестировщики сайтов и орут что размер не оптимален. Эта статья, именно о том, как в пару строк, сделать их оптимальными, при этом, увеличив их качество.

Как рекомендует Google (в англоязычной версии статьи, в русской там какой-то бред) — сжимать картинки лучше всего через ImageMagick. ImageMagick — это такая консольная утилита которая позволяет пережимать и конвертировать данные. Она идет по дефолту во всех Linux системах, разве что, в каких-нибудь core и minimal она может отсутствовать, и то не факт. В Windows, я не знаю, скорее всего, эта штука ставится отдельно, и тут я вам не советник. Придется вам тут разобраться.

Если вы пользуетесь Linux и ваш сервер на Linux, то можно даже особо не париться, эта либа поставляется в виде пакета convert. Если интересно, установлено ли, можно проверить командой convert -version

Version: ImageMagick 6.8.9-9 Q16 x86_64 2017-03-14 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules OpenMP
Delegates: bzlib cairo djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png rsvg tiff wmf x xml zlib

У меня вывел следующий результат. Это значит что всё стоит и работает. Это можно сделать и дальше, точнее, это сделает за вас модуль.

Если у вас шаред хостинг, то тут тоже, ничего вам посоветовать не могу. На VPS вы можете поставить пакет самостоятельно, если отсутствует, что сомнительно. На хостингах скорее всего тоже стоит, но может быть ограничен к ней доступ. Тут уж только проверять. Например, на Drupalhosting доступ есть.

Не ждите от этого гайда чуда, он лишь позволит немного сбросить общий весь картинок, и следовательно вес страницы в целом, примерно на 10-20%, что в свою очередь, ускорит загрузку и все эти проверки-нытики не будут вас доставать.

Но оптимизацией размера и сжатия мы не ограничимся. Через ImageMagick мы можем сделать Progressive PNG\JPG. Это когда картинка на медленном соединении грузится не сверху-внизу, оставляя внизу белый экран, а видна сразу в очень плохом качестве (пиксилизованная) и постепенно прогружается в качестве.

Progressive JPG

Так что убьем сразу двух зайцев.

Сообщаю наперед результаты сжатия для общей картины. У каждой картинки и исходного формата будет разный конечный результат, все сильно зависит от самой картинки, но примерно уловить можно.

Исходный 6000x4000, размер 3.86МБ, jpg. Он пережимается в ноде до 1000х1000, и вот результаты:

  • Сжатие Drupal из коробки, степень сжатия 75% — 106,3кб
  • Сжатие Drupal из коробки, степень сжатия 85% — 144,9кб
  • Сжатие ImageMagick из коробки, степень сжатия 75% — 108,1кб
  • Сжатие ImageMagick из коробки, степень сжатия 85% — 148,3кб
  • Сжатие ImageMagick с оптимизацией, степень сжатия 75% — 103,7кб
  • Сжатие ImageMagick с оптимизацией, степень сжатия 85% — 141.2кб

Как вы можете обратить внимание, ImageMagick из коробки сделает только хуже, его нужно тюнить. Он не может пережать нормально, если ему не обьяснить как. Разница конечно смешная и файл не очень красочный, но везде по чуть-чуть, в итоге серьезно экономится в целом по странице + progression загрузка, что тоже круто.

Установка модуля ImageMagick

Первым делом необходимо установить и включить модуль ImageMagick. После включения перейти на страницу /admin/config/media/image-toolkit и вы увидите что появилось чем пережимать.

Если у вас установлен IM и всё в порядке, раздел Verision Information после выбора IM будет заполнен тем что выводит convert -version. Там же вы можете подкорректировать откуда вызывать данную команду, например для Windows там можно указать путь до .exe, для Linux ничего указывать не нужно, всё настроится самостоятельно. На Drupal 7 будет написано convert, а на Drupal 8 будет пустым.

Обратите внимание что настройки качества хранятся разные, для дефолтного GD2, и IM.

Оптимизируем на Drupal 7

Делается это очень просто, как на 7-ке, так и на 8-ке, но немного отличается код. Модуль ImageMagick предоставляет парочку хуков, которые позволяют нам внедряться на различных этапах сжатия картинки, и мы этим воспользуемся. Нас интересует hook_imagemagick_arguments_alter(), который позволяет добавлять и менять аргументы, которые уйдут команде convert. Основываясь на рекомендациях гугла, нам необходимо использовать -sampling-factor 4:2:0 для более качественного сжатия с меньшими потерями. И для progression изображений мы должны использовать -interlace Plane.

MYMODULE.module
/**
 * Implements hook_imagemagick_arguments_alter().
 */
function MYMODULE_imagemagick_arguments_alter(&$args, $context = array()) {
  # https://developers.google.com/speed/docs/insights/OptimizeImages
  $args['google_advice'] = '-sampling-factor 4:2:0';
  # Progression JPEG and interlaced PNG's support.
  $args['progression'] = '-interlace Plane';
  # Clean image for all unused data. EXIF etcetera.
  $args['strip'] = '-strip';
}

После этого сбрасываем кэш, чтобы хук подцепился.

Теперь, необходимо сбросить все ранее сгенерированные картинки, и при заходе на страницу будут генерироваться новые. Для этого воспользуйтесь drush image-flush --all или конкретный стиль изображения drush image-flush STYLENAME, также можно просто ввести команду без аргумента drush image-flush и он предоставит на выбор какие стили почистить. Это удалит старые изображения и при заходе сгенерирует новые.

Всё!

Drupal 8

Аналогично как и в Drupal 7, только слегка другой код.

MYMODULE.module
/**
 * Implements hook_imagemagick_arguments_alter().
 */
function MYMODULE_imagemagick_arguments_alter(\Drupal\imagemagick\ImagemagickExecArguments $arguments, $command) {
  // https://developers.google.com/speed/docs/insights/OptimizeImages
  $arguments->add('-sampling-factor 4:2:0');
  // Progression JPEG and interlaced PNG's support.
  $arguments->add('-interlace Plane');
  // Clean image for all unused data. EXIF etcetera.
  $arguments->add('-strip');
}

Сброс кэша, drush image-flush и вы готовы!

Вот и всё. Чтобы посмотреть на progression в действии, перейдите в Chrome или в FireFox в режим адаптивного дизайна. У обоих браузеров есть возможность выбор эмуляции скорости интернета. Выбирайте самый маленький, GPRS 50кб\сек, тогда вы увидите насколько круто грузятся теперь изображения при медленном интернете.

UPD Добавлен третий аргумент -strip который срезает приличное кол-во данных. Он удаляет все метаданные у файла, EXIF и тому подобное. Например, файл у меня весил 86кб, только срезав метаданные он уменьшился до 22кб! В обрезанных и оптимизированных изображения эти данные в 99.9% случаях просто не нужны.

UPD 17.06.2017 ImageMagick для Drupal 8 теперь имеет вторую версию. Необходимо отключить (удалить из админки) старый модуль, затем поставить новый. Новый ставится исключительно композером: composer require drupal/imagemagick:~2.0. Если вы не знакомы с композером у меня есть статья про это. Код для 8-ки обновлен в соответствии с API, старый будет еррорить.

Прикрепленные файлы
Сравнения качества сжатия — comparsion.png, 5.29 МБ
Drupal
Drupal 7
Drupal 8
Оптимизация

Комментарии

Антон   чт, 30/03/2017 - 18:47

Большое спасибо! Как раз появилась задача по оптимизации сайта в соотвествии с Google PageSpeed Tools

Plazik   чт, 30/03/2017 - 19:32
  1. Как рекомендует Google Он не рекомендует, там приведен просто пример. В русской версии вообще его нет, там другие программы указаны.

  2. Сравнение сжатия изображений только по размеру бессмысленно. Нужно еще смотреть как они выглядят, есть ли заметные артефакты сжатия и тд, а то можно сжать 3 мб и в 10 кб, но там будет сплошные пиксели :)

Вообще рекомендую другой модуль https://www.drupal.org/project/imageapi_optimize

Niklan   чт, 30/03/2017 - 21:18
  1. Да что-то в русской версии вообще другое написано. Я просто читал в англоязычной, думал русской нет, ну максимум перевод, а там вообще какая-то чушь.

  2. Ну учитывая что приходилось снижать качество до 75%. То новые 85% смотрятся очень заметно лучше, при этом весят меньше и progression работает. А между 85% от IM и GD2 очень сложно заметить. По крайней мере на тех сайтах где я тестил я ничего бросающегося в глаза не заметил.

В чем его отличие от просто ImageMagick? Его меньше использует народу, так он ещё и сам пишет: "Если хотите использовать ImageMagick, пожалуйста используется соответствующий модуль" и линкует на модуль из статьи.

Niklan   пт, 31/03/2017 - 11:49

Прикрепил (и добавил ссылку в статью) на сжатые картинки которые были использованы для теста чтобы посмотреть на качество сжатия. Сама картинка сохранена, разумеется, без сжатия и вставлена ссылкой чтобы Drupal не пережимал.

Shu   чт, 30/03/2017 - 20:14

Спасибо за способ. Использовал вот этот сайт, чтобы сжимать файлы: https://tinypng.com/ Есть модуль под друпал: https://www.drupal.org/project/tinypng В бесплатной версии позволяет сколько-то файлов сжимать. Для маленьких сайтов пойдёт.

Shu   чт, 30/03/2017 - 20:15

При сохранении комментария, кстати такая ошибка вылезла: http://joxi.ru/ZrJOQ0pT9RMB1m

Niklan   чт, 30/03/2017 - 21:21

Да сайт все руки не доходят перекинуть на новый сервак. На текущем я апдейты давно не ставил и вообще подзабил следить за ним, бывает его контузит. Начинает 500 выдавать по всему серваку просто так.

Mozh   пт, 07/07/2017 - 16:30

что-то месяц назад на одном сайте настроил, а теперь не могу на втором. что за ерунда. все уже перенес с рабочего, библиотека установлена. дебаг не заходит в этот хук

Niklan   пт, 07/07/2017 - 16:42

Если Drupal 8, то там новая версия imagemagick и код, соответственно, поменялся слегка в хуке как и аргументы. В статье обновленный код для 8-ки, т.е. для 8.x-2.0. Ставить его нужно через композер, обязательно, иначе работать не будует.

Mozh   пт, 07/07/2017 - 17:01

работает, очень странный затуп был, может редис болтался, кеш чистил много раз. спасибо за материал!

Бумбум   вс, 17/09/2017 - 19:19

Извиняюсь, но немного не понятно - что в этой строке $args['google_advice'] = '-sampling-factor 4:2:0';

означает "google_advice"? Гугль имеет отношение к этому модулю?

Niklan   пн, 18/09/2017 - 10:16

Ничего, просто так назвал ключ в массиве, так как это совет гугла, делать такой sampling factor, по факту, он же и сбивает размер файла. Можно назвать как угодно, тут главное значение, а ключ нигде не используется кроме как в альтере.

Павел   пт, 29/12/2017 - 18:32

Установил всё, как написано в статье, проблема в том, что после всех изменений время загрузки страницы выросло, т.к. он сжимает изображения каждый раз при загрузке страницы. В чём может быть проблема?

Андрей   пт, 20/04/2018 - 17:41

Эффекта пикселизации не наблюдается. Все происходит так же само - загрузка сверху вниз, но быстрее в разы. Пробовал и в Хроме и в Фоксе. Хотел увидеть это чудо)

Niklan   пт, 20/04/2018 - 20:03

Можно включить дев тулз и во вкладке сети в момент загрузки страницы ограничить скорость, например, до 3G — будет видно.

Harry Potter   сб, 25/08/2018 - 14:40

Спасибо

Для стилей изображений, работает хорошо.

Как лучше автоматизировать такую же оптимизацию для оригинальных изображений в imce ?

По умолчанию отдельная директория - "imce".

Редакторы туда загружают.

Алексей   пн, 26/11/2018 - 15:17

эх, что-то экстеншен на windows iis не смог завезти, 3 часа проколупал, хотя ранее на линуксе все ок было

Leonid   чт, 07/03/2019 - 13:31

на странице /admin/config/media/image-toolkit GraphicsMagick пишет, что поддерживается форматы: WebP и JPEG-2000... а как научится теперь конвертировать в эти форматы? в преобразовании в стилях таких форматов нет =/

Stepan   пн, 08/07/2019 - 13:53

Не понял как внедрить Хук. Нужно сделать модуль? Или ImageMagick отредактировать?

Stepan   пн, 08/07/2019 - 14:24

Разобрался, просто добавил аргументов в настройках модуля )) https://pp.userapi.com/c852236/v852236878/169d6d/XHNnExvVVco.jpg

Nikolay   вт, 27/08/2019 - 11:33

Где найти эти настройки? Как сделать, чтобы они появились? Возможно у Вас Drupal 8, а на Drupal 7 таких настроек нет?

Что я сделал:

Код админа сайта я вставил в файл imagemagick.module

/**
 * Implements hook_imagemagick_arguments_alter().
 */
function MYMODULE_imagemagick_arguments_alter(&$args, $context = array()) {
  # https://developers.google.com/speed/docs/insights/OptimizeImages
  $args['google_advice'] = '-sampling-factor 4:2:0';
  # Progression JPEG and interlaced PNG's support.
  $args['progression'] = '-interlace Plane';
  # Clean image for all unused data. EXIF etcetera.
  $args['strip'] = '-strip';
}

Промыл стили изображений.

Результата нет(

Niklan   ср, 28/08/2019 - 07:00
  1. Настроек параметров в Д7 нету и врятли уже будут.
  2. Вы код пишите не там. Почитайте где его писать в Друпал и как.
  3. Помимо кода, ещё надо включить чтобы обработка шла через ImageMagick.
Николай   чт, 12/09/2019 - 15:17

Спасибо за направление! Скажите пожалуйста, где я ошибся:

  1. Создал в папке модуля imagemagick папку с новым модулем imagemagick/mymodule

  2. Там создал 2 файла: imagemagick/mymodule/mymodule.info imagemagick/mymodule/mymodule.module

  3. В imagemagick/mymodule/mymodule.info вставил код:

name = My Module
description = Module for hooks and some functions
core = 7.x
dependencies[] = imagemagick
  1. В imagemagick/mymodule/mymodule.module вставил код:
<?php
function MYMODULE_imagemagick_arguments_alter(&$args, $context = array()) {
  # https://developers.google.com/speed/docs/insights/OptimizeImages
  $args['google_advice'] = '-sampling-factor 4:2:0';
  # Progression JPEG and interlaced PNG's support.
  $args['progression'] = '-interlace Plane';
  # Clean image for all unused data. EXIF etcetera.
  $args['strip'] = '-strip';
}
  1. В /admin/config/media/image-toolkit:
  • ImageMagick включил
  • Путь к фалу convert указал, получил:

Информация о версии

Version: ImageMagick 6.9.7-4 Q16 x86_64 20170114 http://www.imagemagick.org
Copyright: © 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP 
Delegates (built-in): bzlib djvu fftw fontconfig freetype jbig jng jp2 jpeg lcms lqr ltdl lzma openexr pangocairo png tiff wmf x xml zlib
ImageMagick was found and returns this version information.
  1. Включил свой новый модуль "My module"
  2. Промыл стили изображений
  3. Почистил кэш

Ничего не изменилось. Помогите пожалуйста, если есть идеи

Niklan   чт, 12/09/2019 - 15:49

Я бы порекомендовал с таким обьемным вопросом зайти в чатик (ссылка под материалом) и там в лайв режиме обсудить.

Если коротко:

  1. (1) Неправильно, так как вмешиваться в сторонний код запрещено. Это должен быть отдельный модуль либо в sites/all/modules, либо в sites/all/modules/custom.
  2. (4) Если MYMODULE заменили на название модуля, то ок.

Все остальные пункты - ок. Но как вы определили что ничего не изменилось?

Sergiy   пт, 12/02/2021 - 20:35

Желать надо заказ на миллиард, а не миллиард заказов! :))) Вокруг море работы по бросовым ценам, все хотят сайт за 100 евро, а вот тех кто понимает что это и сколько это реально стоит, вот их уже не так много, такой себе ручеёк.. :) Я правильно говорю, Никита?

Michael   чт, 30/04/2020 - 08:14

А масштабируемость изображения IM делает как на этом блоге? Я просто видио смотрел по созданию, но там столько часов что вай-вай и найти повторно большая проблема. В своей конфигурации посмотрел, так и не обнаружил масштабируемость :(

Niklan   чт, 30/04/2020 - 09:49

Что такое масштабирование?

ImageMagick производит операции над картинками. Просто эффективнее чем GD из PHP. Требования выставляет Drupal на основе Стилей изображений. ImageMagick тупо бэкенд, больше он ничего не даёт.

По видео да, сложно искать. Но там везде тайминги с описанием есть и собраны на одной странице, что-то можно найти, наверное :)

Michael   чт, 30/04/2020 - 11:10

А все видимо в мозгах все слилось, давно смотрел просто, это photoswipe, а я почему-то весь функционал отнес к IM :)

Рус   вс, 28/02/2021 - 22:31

Спасибо за статью!

Для тех у кого нет возможности воспользоваться drush будет полезен этот модуль https://www.drupal.org/project/imagestyleflush