Webp в background-image
Создание динамической замены изображения в свойстве background-image на web или jpg.
Оглавление
Всем известно что Google отчаянно продвигает свой любимый формат изображений webp, его поддерживают почти все известные браузеры, окромя IE и Safari. Для авто подмены формата изображений на webp, frontend разработчики используют тег picture
.
Однако, если вам необходимо сделать аналогичную авто подмену изображений в свойстве background-image
, специального тега вы не найдете. Основная задача — не просто подменять изображения, а отдавать только одно, не заставляя грузить оба, т. к. Page Speed Insights будет ныть, найдя изображения в формате jpg. Решение частично было найдено в интернете, частично подсказал мне знакомый товарищ и частично я доработал его, переписав на чистый JavaScript и исправив одну проблему.
Проверка браузера на поддержку Webp
Для начала нам нужна JS функция, которая будет проверять, поддерживает ли браузер формат Webp:
// Проверяем, можно ли использовать Webp формат
function canUseWebp() {
// Создаем элемент canvas
let elem = document.createElement('canvas');
// Приводим элемент к булеву типу
if (!!(elem.getContext && elem.getContext('2d'))) {
// Создаем изображение в формате webp, возвращаем индекс искомого элемента и сразу же проверяем его
return elem.toDataURL('image/webp').indexOf('data:image/webp') == 0;
}
// Иначе Webp не используем
return false;
}
Создав изображение в формате Webp, нам нужно получить его индекс. Результатом метода indexOf()
будет либо 0 — если индекс искомого элемента найден, либо -1 — если не найден. Дело в том, что например браузер IE не создаст нам изображение Webp, т. к. он не умеет работать с этим фарматом и выдаст изображение следующего типа — data:image/png
.
Именно на основании этого мы и будем делать проверку на поддержку Webp. Но есть одно но, Firefox не умеет создавать data:image/webp
из canvas. Следовательно, в браузере который умеет работать с Webp, на основании работы данной функции мы получим отрицательный ответ её выполнения, что конечно не может нас устраивать. Эту проблему я решил, но для начала, давайте напишем JS код, который будет переключать форматы изображений в свойстве background-image
.
Переключатель форматов в background-image
Нам нужно где-то хранить оба формата изображений, чтобы оттуда их цеплять в основное свойство.
Разметка
Мы будем использовать data-атрибуты. По умолчанию указываем в свойстве background-image
изображение в формате webp, а в дата атрибутах распологаем оба формата:
<div style="background-image: url('/images/image.webp')" data-bg="/images/image.jpg" data-bg-webp="/images/image.webp"></div>
JavaScript код
Ну и сам скрипт для замены формата изображений:
window.onload = function () {
// Получаем все элементы с дата-атрибутом data-bg
let images = document.querySelectorAll('[data-bg]');
// Проходимся по каждому
for (let i = 0; i < images.length; i++) {
// Получаем значение каждого дата-атрибута
let image = images[i].getAttribute('data-bg');
// Каждому найденному элементу задаем свойство background-image с изображение формата jpg
images[i].style.backgroundImage = 'url(' + image + ')';
}
// Проверяем, является ли браузер посетителя сайта Firefox и получаем его версию
let isitFirefox = window.navigator.userAgent.match(/Firefox\/([0-9]+)\./);
let firefoxVer = isitFirefox ? parseInt(isitFirefox[1]) : 0;
// Если есть поддержка Webp или браузер Firefox версии больше или равно 65
if (canUseWebp() || firefoxVer >= 65) {
// Делаем все то же самое что и для jpg, но уже для изображений формата Webp
let imagesWebp = document.querySelectorAll('[data-bg-webp]');
for (let i = 0; i < imagesWebp.length; i++) {
let imageWebp = imagesWebp[i].getAttribute('data-bg-webp');
imagesWebp[i].style.backgroundImage = 'url(' + imageWebp + ')';
}
}
};
Как обычно, все комментарии прописал в коде. Отдельно отмечу решение для поддержки браузера Firefox. Не идеально — да, но вполне работает и имеет право на жизнь. Поддержка Webp начинается с версии 65, а значит ниже просто не имеет смысла проверять. Вместо foreach
, можно использовать функцию forEach
— но тогда гуд-бай поддержка IE.
Засим все, если вы скопируете два JS кода выше и сделаете разметку по моему примеру, у вас должны переключаться изображения в инлайновых свойствах background-image
.
Время запросов: 0,1087 s
Количество запросов: 28
Источник: cache