Внедряем webp без боли
Недавно начал работу над очередным проектом, и захотелось сразу добавить поддержку webp (раз такая поддержка уже есть в MODX из коробки). Задача несложная, но хотелось сделать все красиво, да так чтобы менеджеру не нужно было дополнительно эти изображения конвертировать.
По началу была выбрана тактика согласно ГОСТу, то есть просто использовать тег picture. Но уже на этом этапе уже начались проблемы:
Все просто, при сохранении ресурса генерируем с помощью phpThumb нужные изображения с такими же названиями которые используются но в формате webp. Далее веб-сервер сделает все за нас по такой логике:
Нужно определится с размерами которые нам нужны. В качестве примера у меня используется только 1 размер превью с таким конфигом
я его дублирую, при этом к названию добавляю «webp» и указываю нужный тип файла для генерации, остальные параметры оставляю как есть, и у нас получается вот такой конфиг
Если нужны изображения нескольких размерах, тогда для всех проделываем аналогичную процедуру.
Ну и теперь при загрузки фото у нас автоматически будут сгенерированы изображения в двух форматах.
Существующие изображения нужно будет перегенерировать, инструкции для этого можно прямо в сообществе найти. Просто воспользуйтесь поиском.
Примеров генерации превью в разных форматах при сохранении ресурса также можно найти. Но дополнительно скоро выйдет статья по организации рабочего пространства для менеджеров и там будет затронута тема работы с phpThumb в том числе для этих целей.
По началу была выбрана тактика согласно ГОСТу, то есть просто использовать тег picture. Но уже на этом этапе уже начались проблемы:
- Верстка — в css были правила такого рода
div>img {} - Этот тег не поможет, если используется background-image и другие варианты использования изображений в css
- Отображение больших изображений в лайтбоксах (fotorama, fancybox ...)
Решение:
В качестве решения были использованы стандартные возможности веб-сервера (nginx или apache) для подмены изображений если у клиентского браузера есть такая поддержка.Вариант для «контентных» изображений:
Все просто, при сохранении ресурса генерируем с помощью phpThumb нужные изображения с такими же названиями которые используются но в формате webp. Далее веб-сервер сделает все за нас по такой логике:
- проверяем если запрос идет на изображения jpg и png
- смотрим заголовки браузера на наличие accept: image/webp
- если все в порядке ищем рядом изображение с таким же названием только в расширением webp
- если изображение найдено, тогда добавляем заголовок Vary Accept
- отдаем вместо запрошенного изображения то что в формате webp
Пример конфига apache:
создаем файл .htaccess в папке со статикой (у меня это папка /static/ в корне)<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_URI} (.*)(\.(jpe?g|png))$
RewriteCond %{DOCUMENT_ROOT}/%1\.webp -f
RewriteRule .* %1\.webp [L,T=image/webp]
</IfModule>
<IfModule mod_headers.c>
Header append Vary Accept env=REDIRECT_accept
</IfModule>
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>Пример конфига nginx:
аналогично с предыдущим примером (вся статика лежит в папке /static/ в корне)location ~* ^(.*)(/static/.*)(jpg|jpeg|png)$ {
set $webp $1$2webp;
set $rootFile "${document_root}${webp}";
if ($http_accept ~* "webp"){set $test A;}
if (-f $rootFile) {set $test "${test}B";}
if ($test = AB) {
add_header Vary Accept;
rewrite (.*) $webp break;
}
}Вариант для изображений minishop2:
Для начала нам нужно в источнике файлов minishop2 добавить генерацию изображений в этом формате таким образом.Нужно определится с размерами которые нам нужны. В качестве примера у меня используется только 1 размер превью с таким конфигом
{"small":{"w":500,"h":500,"q":90,"zc":"1","bg":"000000"}}я его дублирую, при этом к названию добавляю «webp» и указываю нужный тип файла для генерации, остальные параметры оставляю как есть, и у нас получается вот такой конфиг
{"small":{"w":500,"h":500,"q":90,"zc":"1","bg":"000000"},
"smallwebp":{"w":500,"h":500,"q":90,"zc":"1","bg":"000000","f":"webp"}}Если нужны изображения нескольких размерах, тогда для всех проделываем аналогичную процедуру.
Ну и теперь при загрузки фото у нас автоматически будут сгенерированы изображения в двух форматах.
Существующие изображения нужно будет перегенерировать, инструкции для этого можно прямо в сообществе найти. Просто воспользуйтесь поиском.
Конфиг для apache:
создаем файл .htaccess в папке /assets/images/ с таким содержимым:<IfModule mod_headers.c>
Header append Vary Accept env=REDIRECT_accept
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_URI} ^(.*)(/images/products/.*)(/.*)(/.*)(jpe?g|png)$
RewriteCond %{DOCUMENT_ROOT}%1%2%3webp%4webp -f
RewriteRule ^(.*)$ %1%2%3webp%4webp [L,T=image/webp]
</IfModule>
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule> Конфиг для nginx:
location ~* ^(.*)(/images/products/.*)(/.*)(/.*\.)(jpg|jpeg|png)$ {
set $ext webp;
set $webp $1$2$3$ext$4$ext;
set $rootFile "${document_root}${webp}";
if ($http_accept ~* "webp"){set $test A;}
if (-f $rootFile) {set $test "${test}B";}
if ($test = AB) {
add_header Vary Accept;
rewrite (.*) $webp break;
}
}Примеров генерации превью в разных форматах при сохранении ресурса также можно найти. Но дополнительно скоро выйдет статья по организации рабочего пространства для менеджеров и там будет затронута тема работы с phpThumb в том числе для этих целей.
Комментарии: 34
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Но к примеру можно написать плагин который будет проводить эту процедуру с оригинальными изображениями.
Сначала думал не отображаются из-за формата, но нет, они просто отсутствуют :-)
подробнее тут
Вот пример:
Этот пример был взят с моего сайта, в котором требовалось что бы под разное разрешения была разная картинка и плюс если человек заходит через смартфон с высоким разрешением, то отображается картинка более высокого разрешения :)
Я не могу понять двух вещей.
— так или иначе ленивая загрузка основана на передаче картинки через какой-то дата атрибут. Но разве уже отменили стандарт W3c и его требования к хтмл тегам? Разве может быть тег img без атрибута src ??? Это ведь ошибка.
— разве будут поисковые системы индексировать изображения без src? Мне кажется, что с точки зрения поискового робота сайт вообще будет лишен изображений. Ведь выводом изображения теперь занимается JS скрипт, который существует только в браузере. А поисковый робот заходит не с браузера, а значит ничего кроме ошибок в стандарте он не увидит.
Или я ошибаюсь?
Например: yandex.ru/support/images/indexing.html
В гугле можете проверить через search console.
Хотя на этой же странице есть довольна странная надпись.
И хотя все это конечно дикое нарушение стандарта.
www.w3schools.com/tags/tag_img.asp
И даже если открыть спецификацию более современного тега picture там тоже указано что атрибут src у img обязателен
www.w3schools.com/tags/tag_picture.asp
В src, как я уже сказал, подставляется заглушка (прелоадер), который удаляется как только изображение подгрузилось. Но вот как бот среагирует что во многих src стоит одна и та же заглушка, я не знаю. По сути это не должно ни на что влиять.
Но я говорил немного о другом. о том что такое применение тегов img противоречит стандарту.
По крайней мере пример, указанный Николаем совершенно не содержит атрибута src.
Да я понимаю, что этот атрибут потом появиться, но тут важно понимать, что js скрипт срабатывает и проставит атрибут только в браузере, то есть для пользователя все будет ок. Но поисковый бот не выполняет js скрипты, а значит он будет видеть тег img вот таким
Без атрибута src и соответственно посчитает это ошибкой.
Но может мои знания уже устаревшие и поисковые системы не обращают внимание на ошибки в w3c.
Но важно понимать и другую сторону. Изображения webp весят существенно меньше, а значит страница загружается гораздо быстрее. Ну а скорость загрузки страницы — очевидный фактор ранжирования.
Итого скорость загрузки и вес страницы кладут на обе лопатки отсутствие обязательных атрибутов.
Пишу еще раз — поставьте заглушку в src, дабы не ругался валидатор. Я например по совету @Petr Golovatyy поставил svg-loader иконку. Контент не прыгает, а если и прыгает то 70% пользователей этого не заметят, другим на эту мелочь думаю будет пофиг. К тому же, это касается только контентных изображений.
P.S.
Вообще Петр прям вовремя написал этот пост, потому что вопрос с отдачей web/jpg картинок именно в контенте, вопрос довольно сложный для меня. Если для миниатюр можно заранее задать разметку picture и прописать все атрибуты, но с контентом так не получится. Ну и вариант Петра через конфиги просто идеален.
хотя может быть с src история другая — надо пробовать.
Гущин Сергейdevelopers.google.com/speed/pagespeed/module/?hl=ru
Пример работы этого модуля: golodnaya-panda.ru/
И кстати здесь все же в статье жирными буквами написано то, что я и говорил — поисковик не индексирует изображения, добавленные через скрипты ленивой загрузки.
ru.megaindex.com/blog/lazy-loading-seo
То, что где-то кто-то что-то выделил жирными буквами, еще не значит, что так оно и есть.
И Гугл и Яндекс индексируют изображения с ленивой загрузкой. Это вижу как лично, так и саппорт поисковиков об этом пишет. В любом случае, нужно проверять конкретные случаи, т.к. технология (скрипты) применяются разные. Есть доп.инструменты, которые могут решить проблему и улучшить индексацию — гуглите «schema.org для картинок».
Ради интереса, можете дать ссылку на сайт с ленивой загрузкой картинок, ссылку на гугл фото из этого сайта и на скрипт, которым ленивая загрузка создана? Правда не иронизирую. Реально интересно.
Вот, например
graviruemvse.ru/laser/wood/
Гугл
Яндекс
Причем, Яндекс даже лучше с этим делом справляется.
Большие фото там по data-src="..." лежат, превьюшки под src
Попробую карту для фото делать.
Скрипт lazysizes
А теперь представьте, у меня есть заказчик, который торгует картинами. Сервис по продаже картин. Ориентирован не на Россию, то есть яндекс поиск нам глубоко пофиг.
Основной упор это гугл, площадки типа алиэксперсс, тао бао и так далее.
И будет ли работать ли тут «простая» ленивая загрузка через атрибут data и js скрипт?
Чем больше я вникаю в эту тему, тем чаще вижу ответ от специалистов, что нет — не будет. И это полностью соответствует моему пониманию этого процесса.
У меня загрузились все изображения сразу.
С этим кодом вообще перестаёт выводить изображение и едет корзина И код для apache не срабатывает у меня, но хоть выдодится обычный формат изображений и не едет корзина).
У кого нибудь получилось внедрить webp без боли?)
Нужно ли что-то вносить, включать на сервере.
Фото создались без проблем, но вот как активировать, что бы нужные выбирались не могу разобраться, сейчас просто банально .jpg используется и все.