В 2026 году оптимизация изображений стала критически важной для успеха любого сайта. За последние два года я заметил, что клиенты всё чаще жалуются на медленную загрузку страниц, и в 80% случаев проблема именно в неоптимизированных картинках.
Формат WebP: почему это стандарт 2026 года
Честно говоря, ещё в 2021 году я относился к WebP скептически. Думал — очередной эксперимент Google, который так и останется нишевым решением. Но сейчас поддержка WebP есть в 97% браузеров, и отказываться от него просто глупо.
На практике WebP даёт сжатие на 25-35% лучше, чем JPEG, при том же качестве изображения. У меня был клиент с интернет-магазином обуви — после перехода на WebP размер страницы каталога уменьшился с 3.2 МБ до 2.1 МБ. PageSpeed Insights показал рост с 45 до 78 баллов на мобильных устройствах.
WebP поддерживает как lossy (с потерями), так и lossless (без потерь) сжатие. Плюс альфа-канал для прозрачности и анимацию — по сути, один формат заменяет JPEG, PNG и GIF. Это существенно упрощает работу с изображениями на сайте.
Настройка WebP в Nginx
Самый правильный способ внедрения WebP — настройка на уровне веб-сервера. Я обычно использую Nginx с модулем content negotiation. Вот конфигурация, которую применяю на большинстве проектов:
server {
listen 80;
server_name example.com;
root /var/www/html;
# Проверяем поддержку WebP браузером
location ~* \.(jpe?g|png)$ {
set $webp_suffix "";
if ($http_accept ~* "image/webp") {
set $webp_suffix ".webp";
}
# Пробуем найти WebP версию
try_files $uri$webp_suffix $uri =404;
# Устанавливаем правильный MIME-type
location ~ \.webp$ {
add_header Vary Accept;
add_header Cache-Control "public, max-age=31536000";
}
}
# Кэширование для всех изображений
location ~* \.(jpg|jpeg|png|gif|webp|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept;
}
}
Эта конфигурация автоматически отдаёт WebP-версию изображения, если браузер её поддерживает, и оригинал — если не поддерживает. Главное — не забыть создать WebP-версии всех изображений с тем же именем плюс расширение .webp.
А вот более продвинутая версия с обработкой ошибок:
location ~* \.(jpe?g|png)$ {
set $webp_suffix "";
set $webp_uri $uri;
if ($http_accept ~* "image/webp") {
set $webp_suffix ".webp";
set $webp_uri "${uri}.webp";
}
# Сначала пробуем WebP
try_files $webp_uri $uri =404;
# Логирование для отладки
access_log /var/log/nginx/webp_access.log combined;
}
WebP в Apache через .htaccess
Если у вас Apache (что встречается на shared-хостингах), настройка делается через .htaccess. Честно говоря, это менее элегантное решение, но работает:
RewriteEngine On
# Проверяем поддержку WebP
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_FILENAME} \.(jpe?g|png)$
RewriteCond %{REQUEST_FILENAME}\.webp -f
RewriteRule ^(.+)\.(jpe?g|png)$ $1.$2.webp [T=image/webp,E=accept:1,L]
# Устанавливаем правильные заголовки
<IfModule mod_headers.c>
Header append Vary Accept env=REDIRECT_accept
</IfModule>
# Добавляем MIME-type для WebP
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>
# Кэширование изображений
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
</IfModule>
У меня был проект на WordPress, где хостинг не поддерживал Nginx. Эта .htaccess конфигурация сработала отлично — скорость загрузки главной страницы увеличилась на 40%.
Конвертация изображений в WebP
Массовая конвертация — это отдельная головная боль. Я перепробовал кучу инструментов и остановился на нескольких проверенных решениях.
Для разовой конвертации использую cwebp из пакета webp-tools:
# Установка в Ubuntu/Debian
sudo apt install webp
# Конвертация одного файла
cwebp -q 80 input.jpg -o output.webp
# Массовая конвертация всех JPEG в папке
for file in *.jpg; do
cwebp -q 80 "$file" -o "${file%.jpg}.webp"
done
# Для PNG с альфа-каналом
cwebp -q 80 -lossless input.png -o output.webp
Качество 80 — мой стандартный выбор. Оно даёт хороший баланс между размером файла и качеством изображения. Для фотографий товаров в интернет-магазинах иногда поднимаю до 85-90, для декоративных элементов могу опустить до 70.
На PHP проектах часто использую библиотеку Intervention Image:
<?php
use Intervention\Image\ImageManagerStatic as Image;
// Настройка драйвера
Image::configure(['driver' => 'imagick']);
function convertToWebP($inputPath, $outputPath, $quality = 80) {
try {
$image = Image::make($inputPath);
// Изменяем размер если нужно
if ($image->width() > 1920) {
$image->resize(1920, null, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
}
// Сохраняем в WebP
$image->encode('webp', $quality)->save($outputPath);
return true;
} catch (Exception $e) {
error_log("WebP conversion failed: " . $e->getMessage());
return false;
}
}
// Пример использования
$inputDir = '/var/www/html/images/';
$files = glob($inputDir . '*.{jpg,jpeg,png}', GLOB_BRACE);
foreach ($files as $file) {
$webpFile = pathinfo($file, PATHINFO_DIRNAME) . '/' .
pathinfo($file, PATHINFO_FILENAME) . '.webp';
if (!file_exists($webpFile)) {
convertToWebP($file, $webpFile, 80);
echo "Converted: " . basename($file) . " -> " . basename($webpFile) . "\n";
}
}
Этот скрипт я запускаю через cron раз в день — он автоматически конвертирует новые изображения в WebP. Удобно для сайтов, где контент-менеджеры регулярно загружают фотографии.
Оптимизация размеров изображений
WebP — это только половина дела. Размер изображений не менее важен. В 2026 году я придерживаюсь следующих стандартов:
- Слайдеры и баннеры: максимум 1920×1080px
- Фотографии товаров: 800×800px для превью, 1200×1200px для детального просмотра
- Иконки и логотипы: SVG или PNG до 200×200px
- Миниатюры: не больше 300×300px
Был случай — клиент загружал фотографии товаров прямо с камеры, по 8-12 МБ каждая. Главная страница весила 45 МБ! После оптимизации размеров и конвертации в WebP вес снизился до 2.8 МБ, а время загрузки — с 18 секунд до 3.2 секунды.
Для автоматического ресайза на PHP использую такую функцию:
function optimizeImage($sourcePath, $targetPath, $maxWidth = 1920, $quality = 80) {
$imageInfo = getimagesize($sourcePath);
if (!$imageInfo) return false;
$sourceWidth = $imageInfo[0];
$sourceHeight = $imageInfo[1];
$mimeType = $imageInfo['mime'];
// Вычисляем новые размеры
if ($sourceWidth > $maxWidth) {
$targetWidth = $maxWidth;
$targetHeight = round(($sourceHeight * $maxWidth) / $sourceWidth);
} else {
$targetWidth = $sourceWidth;
$targetHeight = $sourceHeight;
}
// Создаём исходное изображение
switch ($mimeType) {
case 'image/jpeg':
$sourceImage = imagecreatefromjpeg($sourcePath);
break;
case 'image/png':
$sourceImage = imagecreatefrompng($sourcePath);
break;
case 'image/gif':
$sourceImage = imagecreatefromgif($sourcePath);
break;
default:
return false;
}
// Создаём целевое изображение
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
// Сохраняем прозрачность для PNG
if ($mimeType == 'image/png') {
imagealphablending($targetImage, false);
imagesavealpha($targetImage, true);
$transparent = imagecolorallocatealpha($targetImage, 255, 255, 255, 127);
imagefill($targetImage, 0, 0, $transparent);
}
// Ресемплируем
imagecopyresampled(
$targetImage, $sourceImage,
0, 0, 0, 0,
$targetWidth, $targetHeight,
$sourceWidth, $sourceHeight
);
// Сохраняем
$result = false;
if (pathinfo($targetPath, PATHINFO_EXTENSION) == 'webp') {
$result = imagewebp($targetImage, $targetPath, $quality);
} else {
$result = imagejpeg($targetImage, $targetPath, $quality);
}
// Освобождаем память
imagedestroy($sourceImage);
imagedestroy($targetImage);
return $result;
}
Ленивая загрузка изображений
Lazy loading в 2026 году — это уже стандарт, а не дополнительная фича. Браузеры нативно поддерживают атрибут loading="lazy", но я всё равно рекомендую использовать JavaScript-библиотеки для большего контроля.
Нативный lazy loading работает просто:
<img src="image.webp" alt="Описание" loading="lazy" width="800" height="600">
Но у него есть ограничения — нет контроля над порогом загрузки и обработки ошибок. Поэтому на серьёзных проектах я использую Intersection Observer API:
class LazyImageLoader {
constructor(options = {}) {
this.options = {
rootMargin: options.rootMargin || '50px',
threshold: options.threshold || 0.01,
...options
};
this.images = document.querySelectorAll('img[data-src]');
this.imageObserver = null;
this.init();
}
init() {
if (!('IntersectionObserver' in window)) {
this.loadAllImages();
return;
}
this.imageObserver = new IntersectionObserver(
this.onIntersection.bind(this),
this.options
);
this.images.forEach(img => {
this.imageObserver.observe(img);
});
}
onIntersection(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.loadImage(entry.target);
this.imageObserver.unobserve(entry.target);
}
});
}
loadImage(img) {
const src = img.dataset.src;
const srcset = img.dataset.srcset;
// Показываем placeholder во время загрузки
img.style.filter = 'blur(5px)';
img.style.transition = 'filter 0.3s';
const imageLoader = new Image();
imageLoader.onload = () => {
img.src = src;
if (srcset) img.srcset = srcset;
img.style.filter = 'none';
img.classList.add('loaded');
};
imageLoader.onerror = () => {
img.src = '/images/placeholder-error.png';
img.classList.add('error');
};
imageLoader.src = src;
}
loadAllImages() {
this.images.forEach(img => {
img.src = img.dataset.src;
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
});
}
}
// Инициализация
document.addEventListener('DOMContentLoaded', () => {
new LazyImageLoader({
rootMargin: '100px',
threshold: 0.1
});
});
HTML для такой загрузки выглядит так:
<img
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 600'%3E%3C/svg%3E"
data-src="image.webp"
data-srcset="image-400.webp 400w, image-800.webp 800w, image-1200.webp 1200w"
alt="Описание изображения"
width="800"
height="600"
class="lazy-image"
>
У одного клиента после внедрения lazy loading время загрузки главной страницы уменьшилось с 4.2 до 1.8 секунды. На странице было 60+ изображений товаров, и загружались только первые 8-10 в видимой области.
Адаптивные изображения с srcset
В мобильном трафике нет смысла загружать изображения в Full HD разрешении. Атрибут srcset позволяет браузеру выбрать оптимальный размер картинки в зависимости от размера экрана и плотности пикселей.
Вот как я настраиваю responsive images на адаптивных сайтах:
<picture>
<source
media="(max-width: 768px)"
srcset="mobile-400.webp 1x, mobile-800.webp 2x"
type="image/webp"
>
<source
media="(max-width: 1200px)"
srcset="tablet-800.webp 1x, tablet-1200.webp 2x"
type="image/webp"
>
<source
srcset="desktop-1200.webp 1x, desktop-1920.webp 2x"
type="image/webp"
>
<!-- Fallback для старых браузеров -->
<img
src="desktop-1200.jpg"
alt="Описание изображения"
loading="lazy"
>
</picture>
А вот более простой вариант с srcset:
<img
src="image-800.webp"
srcset="image-400.webp 400w,
image-800.webp 800w,
image-1200.webp 1200w,
image-1920.webp 1920w"
sizes="(max-width: 768px) 100vw,
(max-width: 1200px) 50vw,
33vw"
alt="Описание изображения"
loading="lazy"
>
Для автоматической генерации разных размеров использую такой PHP-скрипт:
function generateResponsiveImages($sourcePath, $outputDir, $basename) {
$sizes = [
'mobile' => [400, 600],
'tablet' => [800, 1000],
'desktop' => [1200, 1600],
'large' => [1920, 2400]
];
$results = [];
foreach ($sizes as $name => $dimensions) {
foreach ($dimensions as $width) {
// JPEG версия
$jpegPath = $outputDir . $basename . '-' . $width . '.jpg';
if (optimizeImage($sourcePath, $jpegPath, $width, 85)) {
$results[$name]['jpeg'][] = $jpegPath;
}
// WebP версия
$webpPath = $outputDir . $basename . '-' . $width . '.webp';
if (optimizeImage($sourcePath, $webpPath, $width, 80)) {
$results[$name]['webp'][] = $webpPath;
}
}
}
return $results;
}
function generatePictureTag($images, $alt, $basename) {
$html = "<picture>\n";
// WebP sources
foreach ($images as $device => $formats) {
if (isset($formats['webp']) && count($formats['webp']) > 0) {
$srcset = [];
foreach ($formats['webp'] as $path) {
$width = basename($path, '.webp');
$width = substr($width, strrpos($width, '-') + 1);
$srcset[] = $path . ' ' . $width . 'w';
}
$media = '';
switch ($device) {
case 'mobile':
$media = ' media="(max-width: 768px)"';
break;
case 'tablet':
$media = ' media="(max-width: 1200px)"';
break;
}
$html .= ' <source' . $media . ' srcset="' . implode(', ', $srcset) . '" type="image/webp">' . "\n";
}
}
// Fallback JPEG
if (isset($images['desktop']['jpeg'][0])) {
$html .= ' <img src="' . $images['desktop']['jpeg'][0] . '" alt="' . htmlspecialchars($alt) . '" loading="lazy">' . "\n";
}
$html .= "</picture>";
return $html;
}
CDN и облачная оптимизация изображений
Для крупных проектов ручная оптимизация изображений становится неэффективной. Я всё чаще использую облачные сервисы для автоматической обработки картинок.
Cloudinary — мой фаворит среди таких сервисов. Вот как я его настраиваю:
// Конфигурация Cloudinary
const cloudinary = require('cloudinary').v2;
cloudinary.config({
cloud_name: 'your-cloud-name',
api_key: 'your-api-key',
api_secret: 'your-api-secret'
});
// Функция для генерации оптимизированного URL
function getOptimizedImageUrl(publicId, options = {}) {
const defaultOptions = {
fetch_format: 'auto', // Автоматический выбор формата (WebP если поддерживается)
quality: 'auto:good', // Автоматическая оптимизация качества
width: 'auto', // Автоматический размер на основе DPR
dpr: 'auto', // Автоматическая плотность пикселей
crop: 'fill',
gravity: 'auto' // Умная обрезка
};
return cloudinary.url(publicId, { ...defaultOptions, ...options });
}
// Примеры использования
const mobileImageUrl = getOptimizedImageUrl('sample-image', {
width: 400,
height: 300
});
const desktopImageUrl = getOptimizedImageUrl('sample-image', {
width: 1200,
height: 800,
quality: 'auto:best'
});
А если бюджет не позволяет Cloudinary, настраиваю собственное решение с ImageMagick на сервере:
class ImageOptimizer {
private $cacheDir;
private $maxAge = 31536000; // 1 год
public function __construct($cacheDir = '/var/www/cache/images/') {
$this->cacheDir = $cacheDir;
if (!is_dir($this->cacheDir)) {
mkdir($this->cacheDir, 0755, true);
}
}
public function optimize($imagePath, $width = null, $height = null, $quality = 80, $format = 'webp') {
// Генерируем ключ для кэша
$cacheKey = md5($imagePath . $width . $height . $quality . $format);
$cachedPath = $this->cacheDir . $cacheKey . '.' . $format;
// Проверяем кэш
if (file_exists($cachedPath) &&
filemtime($cachedPath) > filemtime($imagePath)) {
return $cachedPath;
}
// Оптимизируем изображение
$imagick = new Imagick($imagePath);
// Изменяем размер если нужно
if ($width || $height) {
$imagick->resizeImage(
$width ?: 0,
$height ?: 0,
Imagick::FILTER_LANCZOS,
1,
!($width && $height) // Сохраняем пропорции если задан только один размер
);
}
// Устанавливаем формат и качество
$imagick->setImageFormat($format);
if (in_array($format, ['jpg', 'jpeg', 'webp'])) {
$imagick->setImageCompressionQuality($quality);
}
// Удаляем EXIF данные
$imagick->stripImage();
// Сохраняем
$imagick->writeImage($cachedPath);
$imagick->destroy();
return $cachedPath;
}
public function serve($imagePath, $params = []) {
$width = isset($params['w']) ? (int)$params['w'] : null;
$height = isset($params['h']) ? (int)$params['h'] : null;
$quality = isset($params['q']) ? (int)$params['q'] : 80;
$format = isset($params['f']) ? $params['f'] : 'webp';
// Проверяем поддержку WebP
if ($format === 'webp' && !$this->supportsWebP()) {
$format = 'jpg';
}
$optimizedPath = $this->optimize($imagePath, $width, $height, $quality, $format);
// Отдаём файл с правильными заголовками
header('Content-Type: image/' . $format);
header('Cache-Control: public, max-age=' . $this->maxAge);
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $this->maxAge) . ' GMT');
readfile($optimizedPath);
exit;
}
private function supportsWebP() {
return strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'image/webp') !== false;
}
}
Про настройку CDN я подробно писал в статье о настройке CDN для сайта — рекомендую изучить, если планируете серьёзную оптимизацию.
WebP в WordPress
WordPress с версии 5.8 поддерживает WebP нативно, но я всё равно рекомендую использовать специализированные плагины для большего контроля над процессом оптимизации.
Мои топ-3 плагина для оптимизации изображений в WordPress:
- ShortPixel Image Optimizer — лучший по качеству сжатия, есть API для массовой обработки
- Smush — хорош для новичков, простая настройка
- EWWW Image Optimizer — максимум настроек, работает локально
Но честно говоря, я предпочитаю настраивать оптимизацию на уровне кода. Вот функции, которые добавляю в functions.php:
// Добавляем поддержку WebP
function add_webp_upload_mimes($existing_mimes) {
$existing_mimes['webp'] = 'image/webp';
return $existing_mimes;
}
add_filter('mime_types', 'add_webp_upload_mimes');
// Автоматическая конвертация загружаемых изображений в WebP
function auto_convert_to_webp($metadata, $attachment_id) {
$upload_dir = wp_upload_dir();
$file_path = get_attached_file($attachment_id);
$file_info = pathinfo($file_path);
// Проверяем, что это изображение JPEG или PNG
if (!in_array(strtolower($file_info['extension']), ['jpg', 'jpeg', 'png'])) {
return $metadata;
}
// Путь для WebP версии
$webp_path = $file_info['dirname'] . '/' . $file_info['filename'] . '.webp';
// Конвертируем в WebP
if (function_exists('imagewebp')) {
$image = null;
switch (strtolower($file_info['extension'])) {
case 'jpg':
case 'jpeg':
$image = imagecreatefromjpeg($file_path);
break;
case 'png':
$image = imagecreatefrompng($file_path);
// Сохраняем прозрачность
imagealphablending($image, false);
imagesavealpha($image, true);
break;
}
if ($image) {
imagewebp($image, $webp_path, 80);
imagedestroy($image);
}
}
// Создаём WebP версии для всех размеров
if (isset($metadata['sizes']) && is_array($metadata['sizes'])) {
foreach ($metadata['sizes'] as $size_name => $size_info) {
$size_file_path = $upload_dir['path'] . '/' . $size_info['file'];
$size_file_info = pathinfo($size_file_path);
$size_webp_path = $size_file_info['dirname'] . '/' . $size_file_info['filename'] . '.webp';
if (file_exists($size_file_path)) {
$size_image = null;
switch (strtolower($size_file_info['extension'])) {
case 'jpg':
case 'jpeg':
$size_image = imagecreatefromjpeg($size_file_path);
break;
case 'png':
$size_image = imagecreatefrompng($size_file_path);
imagealphablending($size_image, false);
imagesavealpha($size_image, true);
break;
}
if ($size_image) {
imagewebp($size_image, $size_webp_path, 80);
imagedestroy($size_image);
}
}
}
}
return $metadata;
}
add_filter('wp_generate_attachment_metadata', 'auto_convert_to_webp', 10, 2);
// Функция для получения WebP URL изображения
function get_webp_image_url($attachment_id, $size = 'full') {
$image_url = wp_get_attachment_image_url($attachment_id, $size);
if (!$image_url) return false;
$image_path = get_attached_file($attachment_id);
if ($size !== 'full') {
$image_meta = wp_get_attachment_metadata($attachment_id);
if (isset($image_meta['sizes'][$size])) {
$upload_dir = wp_upload_dir();
$image_path = $upload_dir['path'] . '/' . $image_meta['sizes'][$size]['file'];
}
}
$path_info = pathinfo($image_path);
$webp_path = $path_info['dirname'] . '/' . $path_info['filename'] . '.webp';
if (file_exists($webp_path)) {
return str_replace(
$path_info['basename'],
$path_info['filename'] . '.webp',
$image_url
);
}
return $image_url;
}
Эти функции автоматически создают WebP-версии всех загружаемых изображений. Плюс можно получить WebP URL через функцию get_webp_image_url(). Подробнее о том, как ускорить WordPress, я писал в отдельной статье.
Мониторинг и измерение результатов
Оптимизация без измерения результатов — пустая трата времени. Я всегда отслеживаю несколько ключевых метрик до и после внедрения WebP.
Основные инструменты для мониторинга:
- PageSpeed Insights — показывает экономию трафика от WebP
- GTmetrix — детальный анализ времени загрузки изображений
- WebPageTest — тестирование с разных локаций и устройств
- Chrome DevTools — анализ Network tab в реальном времени
Для автоматического мониторинга настраиваю простой скрипт, который проверяет процент WebP-изображений на сайте:
function analyzeImageFormats($url) {
$html = file_get_contents($url);
if (!$html) return false;
$dom = new DOMDocument();
@$dom->loadHTML($html);
$images = $dom->getElementsByTagName('img');
$totalImages = $images->length;
$webpImages = 0;
$totalSize = 0;
$webpSize = 0;
foreach ($images as $img) {
$src = $img->getAttribute('src');
if (!$src) continue;
// Делаем URL абсолютным
if (strpos($src, 'http') !== 0) {
$src = rtrim($url, '/') . '/' . ltrim($src, '/');
}
// Получаем информацию о файле
$headers = @get_headers($src, true);
if (!$headers) continue;
$contentLength = isset($headers['Content-Length']) ?
(int)$headers['Content-Length'] : 0;
$contentType = isset($headers['Content-Type']) ?
$headers['Content-Type'] : '';
$totalSize += $contentLength;
if (strpos($contentType, 'webp') !== false) {
$webpImages++;
$webpSize += $contentLength;
}
}
return [
'total_images' => $totalImages,
'webp_images' => $webpImages,
'webp_percentage' => $totalImages > 0 ? round(($webpImages / $totalImages) * 100, 2) : 0,
'total_size' => $totalSize,
'webp_size' => $webpSize,
'size_savings' => $totalSize > 0 ? round((($totalSize - $webpSize) / $totalSize) * 100, 2) : 0
];
}
// Пример использования
$stats = analyzeImageFormats('https://example.com');
echo "WebP изображений: {$stats['webp_percentage']}%\n";
echo "Экономия трафика: {$stats['size_savings']}%\n";
Этот скрипт запускаю через cron раз в день и отправляю результаты в Slack. Помогает отслеживать, что все изображения действительно отдаются в оптимальном формате.
А для мониторинга Core Web Vitals использую комбинацию Google Analytics 4 и собственных метрик. Подробнее об улучшении Core Web Vitals я писал в отдельной статье.
Типичные ошибки и их решения
За годы работы с WebP я наступил на все возможные грабли. Вот самые частые проблемы и их решения:
Проблема №1: WebP не отображается в Safari
Safari на macOS поддерживает WebP с версии 14, но на iOS — только с 14-й версии. Обязательно настраивайте fallback на JPEG/PNG.
Проблема №2: Неправильные MIME-типы
Некоторые хостинги не знают MIME-тип для WebP. Добавьте в .htaccess:
AddType image/webp .webp
Проблема №3: Кэширование старых изображений
После конвертации в WebP браузеры могут продолжать показывать старые JPEG. Очищайте кэш CDN и добавляйте версионность:
<img src="image.webp?v=93" alt="Изображение">
Проблема №4: Размер WebP больше оригинала
Иногда WebP может быть больше PNG для простых изображений с малым количеством цветов. В таких случаях лучше оставить PNG.
Проблема №5: Потеря прозрачности
При конвертации PNG в WebP можно потерять альфа-канал. Используйте параметр -lossless для изображений с прозрачностью:
cwebp -lossless input.png -o output.webp
У одного клиента была интересная проблема — WebP изображения загружались, но не кэшировались браузером. Оказалось, что сервер отдавал неправильный заголовок Vary. Решение:
location ~* \.webp$ {
add_header Vary "Accept, Accept-Encoding";
add_header Cache-Control "public, max-age=31536000, immutable";
}
В 2026 году оптимизация изображений — это не просто "сделал и забыл". Это постоянный процесс мониторинга, тестирования и улучшения. WebP значительно ускоряет загрузку сайтов, но только при правильной настройке всей цепочки: от конвертации до отдачи через CDN.
Если у вас возникают сложности с настройкой WebP или оптимизацией изображений, всегда можно обратиться за профессиональной поддержкой сайта — это сэкономит время и избавит от головной боли с техническими нюансами.
Нужна помощь с оптимизацией изображений на сайте?
Поможем настроить WebP и ускорить загрузку вашего сайта до 70%.
