Каждый веб-разработчик рано или поздно сталкивается с проблемой: сайт грузится медленно, а виноваты в этом чаще всего изображения. Тяжёлые JPEG и PNG пожирают трафик, заставляя пользователей нервничать. Решение уже давно существует — формат WebP, который обеспечивает отличное качество при меньшем весе. Но как его внедрить в свой PHP-проект? Давайте разберёмся.

Digital-студия WNDER

В этой статье я расскажу, как подружить PHP с WebP: от простой конвертации до автоматической оптимизации сайта. Вы узнаете, как заставить ваши картинки весить на 30-50% меньше, сохраняя при этом чёткость и детализацию. Готовы? Поехали.

Почему WebP — это не просто модно, а необходимо?

WebP — это формат изображений, разработанный Google. Его главное преимущество — эффективное сжатие. Он использует современные алгоритмы, которые позволяют уменьшить размер файла без видимой потери качества. По сравнению с JPEG, WebP обычно даёт экономию от 25% до 35%, а с PNG — до 50%. Это значит, что страницы загружаются быстрее, трафик расходуется экономнее, а пользователи остаются довольны.

Поддержка WebP сегодня есть во всех современных браузерах: Chrome, Firefox, Opera, Edge, даже Safari (с версии 14). Так что проблем с совместимостью практически нет. А если какой-то старый браузер не поддерживает формат, мы легко можем предусмотреть запасной вариант.

Проверяем, поддерживает ли сервер WebP

Прежде чем писать код, нужно убедиться, что ваш PHP и сервер вообще умеют работать с WebP. Для этого достаточно вызвать функцию imagewebp() или проверить список поддерживаемых форматов через gd_info().


<?php
// Проверяем, поддерживает ли GD библиотека WebP
if (function_exists('imagewebp')) {
    echo 'WebP поддерживается!';
} else {
    echo 'WebP не поддерживается. Установите расширение GD с поддержкой WebP.';
}

// Более детальная проверка
$gdInfo = gd_info();
echo $gdInfo['WebP Support'] ? 'WebP включён' : 'WebP отключён';
?>

Если функция не найдена, значит, нужно включить поддержку. В большинстве случаев достаточно установить расширение php-gd или php-imagick на сервере. Например, для Ubuntu это делается командой:


sudo apt-get install php-gd
sudo service apache2 restart

Если вы используете Imagick, то проверка будет выглядеть так:


<?php
if (extension_loaded('imagick')) {
    $imagick = new Imagick();
    $formats = $imagick->queryFormats();
    if (in_array('WEBP', $formats)) {
        echo 'Imagick поддерживает WebP';
    } else {
        echo 'Imagick не поддерживает WebP';
    }
} else {
    echo 'Imagick не установлен';
}
?>

Конвертируем изображения в WebP с помощью GD

Самое простое — использовать GD, который есть почти везде. Напишем функцию, которая принимает путь к файлу и конвертирует его в WebP.


<?php
function convertToWebP($sourcePath, $destinationPath, $quality = 80) {
    // Получаем информацию о файле
    $info = getimagesize($sourcePath);
    if ($info === false) {
        return false;
    }

    // Создаём изображение в зависимости от типа
    switch ($info['mime']) {
        case 'image/jpeg':
            $image = imagecreatefromjpeg($sourcePath);
            break;
        case 'image/png':
            $image = imagecreatefrompng($sourcePath);
            // Для PNG нужно сохранять альфа-канал
            imagepalettetotruecolor($image);
            imagealphablending($image, true);
            imagesavealpha($image, true);
            break;
        case 'image/gif':
            $image = imagecreatefromgif($sourcePath);
            break;
        default:
            return false;
    }

    // Конвертируем в WebP
    $result = imagewebp($image, $destinationPath, $quality);
    imagedestroy($image);

    return $result;
}

// Пример использования
convertToWebP('photo.jpg', 'photo.webp', 85);
?>

Обратите внимание на параметр $quality. Для фотографий обычно используют 80-85, для скриншотов и графики можно поставить 90-95. Чем выше качество, тем больше размер файла, но всё равно меньше, чем у JPEG.

Работаем с WebP через Imagic — больше возможностей

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


<?php
function convertWithImagick($sourcePath, $destinationPath, $quality = 80, $width = null) {
    $imagick = new Imagick($sourcePath);

    // Если задана ширина, пропорционально меняем размер
    if ($width !== null) {
        $imagick->resizeImage($width, 0, Imagick::FILTER_LANCZOS, 1);
    }

    // Устанавливаем качество
    $imagick->setImageFormat('webp');
    $imagick->setImageCompressionQuality($quality);

    // Сохраняем
    $imagick->writeImage($destinationPath);
    $imagick->clear();
}

// Пример: уменьшаем до 1200 пикселей по ширине
convertWithImagick('big-photo.jpg', 'optimized.webp', 80, 1200);
?>

Imagick также умеет обрабатывать анимации и более сложные операции, такие как поворот, обрезка или добавление водяных знаков. Если у вас есть выбор, я рекомендую использовать именно его.

Автоматическая конвертация при загрузке файлов

Часто возникает задача: пользователь загружает изображение через форму, а мы хотим автоматически сохранить его в WebP. Сделаем это на примере простой формы.


<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="image" accept="image/*">
    <button type="submit">Загрузить</button>
</form>

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
    $file = $_FILES['image'];

    // Проверяем ошибки загрузки
    if ($file['error'] !== UPLOAD_ERR_OK) {
        die('Ошибка загрузки');
    }

    // Проверяем, что это изображение
    $allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
    $mime = mime_content_type($file['tmp_name']);
    if (!in_array($mime, $allowedTypes)) {
        die('Неподдерживаемый формат');
    }

    // Создаём уникальное имя
    $uploadDir = 'uploads/';
    $webpName = uniqid() . '.webp';
    $webpPath = $uploadDir . $webpName;

    // Конвертируем в WebP
    if (convertToWebP($file['tmp_name'], $webpPath, 80)) {
        echo 'Файл успешно загружен: ' . $webpPath;
        // Здесь можно сохранить путь в базу данных
    } else {
        echo 'Не удалось конвертировать изображение';
    }
}
?>

Обратите внимание: мы не сохраняем оригинал, чтобы не занимать лишнее место. Но если нужна возможность скачать исходник, сохраняйте оба файла.

Правило: всегда проверяйте MIME-тип загружаемого файла, а не только расширение. Пользователь может переименовать вредоносный файл в .jpg, и тогда вы рискуете получить на сервере что-то опасное.

Вывод WebP с запасным вариантом через тег picture

Теперь, когда у нас есть WebP-файлы, нужно правильно выводить их в браузер. Используем тег <picture>, который позволяет указать несколько источников. Браузер выберет первый поддерживаемый.


<picture>
    <source srcset="photo.webp" type="image/webp">
    <img src="photo.jpg" alt="Фотография" loading="lazy">
</picture>

Если браузер не поддерживает WebP, он проигнорирует тег <source> и загрузит JPEG. Такой подход гарантирует, что изображение увидит любой пользователь.

Оптимизация качества: как подобрать идеальный баланс

Качество WebP — величина непостоянная. Иногда можно поставить 70 и получить отличный результат, а иногда даже 90 недостаточно. Я рекомендую экспериментировать. Но есть несколько общих правил:

  • Для фотографий — качество 80-85. На этом уровне потери практически незаметны.
  • Для скриншотов и интерфейсов — 90-95, чтобы сохранить чёткость текста и линий.
  • Для декоративных элементов и фонов — можно снизить до 60-70, если они не содержат мелких деталей.
Тип изображения Рекомендуемое качество Экономия по сравнению с JPEG
Фотографии 80-85 25-35%
Скриншоты 90-95 40-50%
Логотипы и графика 90-95 30-40%

Кэширование конвертированных изображений

Конвертация изображений — операция затратная по ресурсам. Если у вас на сайте тысячи картинок, конвертировать каждую при каждом запросе — непозволительная роскошь. Лучше сделать это один раз и закэшировать результат.


<?php
function getWebP($sourcePath, $quality = 80) {
    $cachePath = 'cache/' . md5($sourcePath . $quality) . '.webp';

    // Если уже есть в кэше, возвращаем
    if (file_exists($cachePath)) {
        return $cachePath;
    }

    // Конвертируем и сохраняем в кэш
    if (convertToWebP($sourcePath, $cachePath, $quality)) {
        return $cachePath;
    }

    // Если не получилось, возвращаем оригинал
    return $sourcePath;
}

// Использование
echo '<img src="' . getWebP('images/photo.jpg') . '" alt="Фото">';
?>

Этот подход экономит процессорное время и ускоряет загрузку страниц. Кэш можно периодически очищать, если исходные изображения обновляются.

Лайфхак: используйте имя файла как основу для кэша. Например, photo.jpgphoto.webp. Так проще ориентироваться и можно удалить кэш, если исходник изменился.

Что в итоге?

WebP — это не просто очередная фишка, а реальный способ ускорить ваш сайт и сэкономить трафик. С PHP подключить его несложно:

  • Проверьте поддержку GD или Imagick.
  • Напишите функцию конвертации.
  • Используйте тег <picture> для запасного варианта.
  • Не забывайте про кэширование.

Попробуйте внедрить WebP на своём проекте — и вы заметите разницу в скорости уже после первых изменений. А если что-то пойдёт не так, пишите в комментариях — помогу разобраться. Удачи!

Студия WNDER