WebP вместо изображений в браузерах где он поддерживается

В данной статье приведены примеры как сделать подгрузку WebP вместо jpg и png в тех браузерах где он поддерживается.

Самый быстрый способ – конвертировать изображения с помощью утилиты cwebp (если он установлен на сервере) через SSH.

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

find /public_html/www -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -exec sh -c 'cwebp -lossless $1 -o "${1%.*}.webp"' _ {} \;

/public_html/www – директория, в которой будет осуществляться поиск. Если указать ./ то поиск и конвертация пройдет на всем сервере.

Cwebp в работе
Cwebp в работе

Если сайт очень редко обновляется, то можно выкачивать весь сайт по FTP, конвертировать изображение и закачать обратно.

Пакетно перекодировать изображения можно с помощью программы XnConvert.

Добавление директории с файлами сайта
Добавление директории с файлами сайта
Настройки конвертации в WebP
Настройки конвертации в WebP
Процесс конвертации в WebP
Процесс конвертации в WebP

Еще один вариант конвертации – PHP-скрипт, который вызывается по URL на несуществующий файл *.webp, ищет в той же директории файл с расширением png или jpg и создает из него файл WebP.

Главное чтобы на хостинге была установлена библиотека GD версией не ниже 2.2.5, т.к. в более ранних версиях у WebP нет поддержки прозрачности при конвертации из PNG.

Посмотреть версию GD можно в phpinfo():

Для работы скрипта нужно добавить правило в корневой файл .httaccess.

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} /uploads/.*?\.webp$
RewriteRule ^(.*)$ auto-webp.php [L]
htaccess

auto-webp.php

<?php
	
//phpinfo();  
	
/* Путь до корневой директории сайта */
$base_dir = __DIR__;

if (!empty($_SERVER['REQUEST_URI']) && !is_file($base_dir . $_SERVER['REQUEST_URI'])) {
	/* Разбор полученного URL */
	$url = explode('?', trim($_SERVER['REQUEST_URI'], '/'));
	$new = $base_dir . '/' . $url[0]; 
	$file = preg_replace('/\.webp$/', '', $new); 

	// Поиск оригинального файла (png или jpg), с учетом регистра.
	$src = '';
	foreach (array('PNG', 'PNG', 'jpg', 'JPG', 'jpeg', 'JPEG', 'png') as $row) {
		if (is_file($file . '.' . $row)) {
			$src = $file . '.' . $row;
			break;
		}
	}

	// Преобразование
	if (!empty($src)) {
		$img = false;
		$info = getimagesize($src);
		switch ($info[2]) { 				
			case 2: 	
				$img = imageCreateFromJpeg($src);
				imageWebp($src, $new, 100);
				imagedestroy($img);
				break;
			case 3:
				$img = imageCreateFromPng($src);
				imagepalettetotruecolor($img);
				imagealphablending($img, true);
				imagesavealpha($img, true);
				imageWebp($img, $new, 100);
				imagedestroy($img);		
				break;
		}


		if ($img) {
			//fix for corrupted WEBPs
			if (filesize($new) % 2 == 1) {
				file_put_contents($new, "\0", FILE_APPEND);
			}	
			
			// Вывод webp в браузер
			header('Content-Length: ' . filesize($new));
			readfile($new);	
			exit();
		}
	}
}
 
header('HTTP/1.0 404 Not Found');
exit();
PHP

После выбора метода и генерации изображений встает вопрос о выводе их на сайте, специально для этого есть элементы <picture> и <source>, которые дают возможность браузеру выбрать более подходящее для него формат.

По спецификации изображение WebP правильно вывести в таком виде, с дублированием основного изображения.

<picture>
	<source type="image/webp" srcset="/image.webp">
	<source type="image/png" srcset="/image.png">
	<img src="/image.png" alt="">
</picture>
HTML

Но во всех браузерах работает и так:

<picture>
	<source type="image/webp" srcset="/image.webp">
	<img src="/image.png" alt="">
</picture>
HTML
Если изображения выводятся на страницы сайта из БД в PHP-скриптах, то сделать вывод можно следующим образом:
<?php
$img = '/uploads/image.png';
$webp = preg_replace('".(jpg|jpeg|png)$"', '.webp', $img);
?>

<picture>
	<source type="image/webp" srcset="<?php echo $webp; ?>">
	<img src="<?php echo $img; ?>" alt="">
</picture>
HTML

Второй вариант – полная замена расширений в тегах <img> если браузер передал в user agent что поддерживает WebP с помощью PHP буферизации и её функции обратного вызова.

<?php
ob_start('set_webp');

function set_webp($html) {
	if (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false) {
		$html = str_ireplace(array('.jpg"', '.jpeg"', '.png"'), '.webp"', $html);
	}	

	return $html;
}

....
PHP
08.10.2020, обновлено 07.06.2021
5628
Предыдущая запись Input type number
Следующая запись Синхронная задержка в JS

Комментарии 1

Evgenii Morozov Evgenii Morozov
22 января 2021 в 15:44
0
Для поддержки WEBP формата в MODX - https://github.com/commeta/modxWebpConverterУмеет генерировать webp копии картинок, и вставлять их на лету.

, чтобы добавить комментарий.

Другие публикации

Генерация превьюшек изображений на лету
В движках интернет магазинов, часто при добавлении товара и загрузке его фото, на сервере сразу генерируются превью...
3444
+2
Повышение результатов PageSpeed Insights
Сборник советов как поднять оценку в PageSpeed Insights.
10239
+2
Загрузка файлов на сервер PHP
В статье приведен пример формы и php-скрипта для безопасной загрузки файлов на сервер, возможные ошибки и рекомендации при работе с данной темой.
45163
+17
Примеры использования cURL в PHP
cURL PHP – это библиотека предназначенная для получения и передачи данных через такие протоколы, как HTTP, FTP, HTTPS....
115906
+16
Автоматическое сжатие и оптимизация картинок на сайте
Изображения нужно сжимать для ускорения скорости загрузки сайта, но как это сделать? На многих хостингах нет...
15906
+8
Описание мета-тегов
В статье представлены все самые встречающеюся мета-теги с примерами и пояснениями их использования.
11820
+3