Формат AVIF для сайта: настройка и оптимизация в 2026

AVIF в 2026 году — это уже не "экзотика для экспериментаторов", а стандарт де-факто для оптимизации изображений. Я перешёл на него почти на всех своих проектах, и сейчас расскажу, как именно это сделать — от настройки сервера до интеграции с CMS.

Что такое AVIF и почему это важно прямо сейчас

AVIF (AV1 Image File Format) — это формат изображений, основанный на видеокодеке AV1. Разработан Alliance for Open Media, куда входят Google, Mozilla, Microsoft, Netflix и ещё добрый десяток крупных компаний. Если коротко: AVIF сжимает картинки значительно лучше, чем JPEG, PNG и даже WebP, при этом сохраняя качество на приемлемом уровне.

На практике я получаю экономию от 40% до 70% по сравнению с JPEG при визуально идентичном качестве. Был у меня клиент — интернет-магазин сантехники, около 8000 товарных изображений. Переконвертировали всё из JPEG в AVIF, папка с картинками похудела с 4.2 GB до 1.1 GB. PageSpeed Insights на мобильных вырос с 54 до 81. Это не магия — это физика сжатия.

AVIF поддерживает: HDR и широкий цветовой охват, прозрачность (альфа-канал), анимацию, 12-битную глубину цвета. По поддержке браузеров ситуация в 2026 году отличная: Chrome (с версии 85), Firefox (с 93), Safari (с 16.4), Edge — все поддерживают. Единственное исключение — Internet Explorer, но если ты до сих пор поддерживаешь IE, у тебя проблемы серьёзнее форматов изображений.

ℹ️
Поддержка браузеров: По данным caniuse.com, AVIF поддерживается у 93%+ пользователей глобально. В России эта цифра чуть ниже из-за устаревших версий браузеров, но всё равно выше 88%. Для остальных всегда делаем fallback на WebP или JPEG — об этом ниже.

Сравнение форматов при качестве q=75 (мои личные замеры на реальных проектах):

Разница между WebP и AVIF особенно заметна на фотографиях с градиентами, человеческими лицами и природными сценами. На иконках и простой графике разница менее драматичная, но всё равно есть.

Конвертация изображений в AVIF: инструменты и подходы

Начну с серверной стороны, потому что именно там происходит основная работа. Для конвертации я использую несколько инструментов в зависимости от задачи.

libavif и avifenc

Это эталонный энкодер от разработчиков формата. Устанавливается на Ubuntu/Debian так:

apt-get install libavif-dev libavif-bin

# Конвертация одного файла
avifenc --min 20 --max 35 --speed 6 input.jpg output.avif

# Массовая конвертация через find
find /var/www/site/upload -name "*.jpg" | while read f; do
    avifenc --min 20 --max 35 --speed 6 "$f" "${f%.jpg}.avif"
done

Параметры --min и --max задают диапазон качества (меньше число — лучше качество, больше файл). Я обычно использую 20-35 для фотографий и 15-25 для продуктовых изображений, где важна детализация. Параметр --speed от 0 до 10: 0 — максимальное сжатие, очень долго; 10 — быстро, но хуже. Для продакшена оптимально 4-6.

ImageMagick и libvips

ImageMagick умеет в AVIF начиная с версии 7.1, но через libheif. На практике libvips работает быстрее и даёт лучшие результаты:

# Установка libvips с поддержкой AVIF
apt-get install libvips-tools

# Конвертация через vips
vips copy input.jpg output.avif[Q=70,effort=4]

# Или через командную строку vipsheader + vipsthumbnail
vipsthumbnail input.jpg --size 1920 -o output.avif[Q=70]

В PHP я использую расширение vips для PHP (pecl install vips) или просто вызываю консольные утилиты через exec() — зависит от задачи. Для Bitrix-проектов у меня есть отдельный модуль, который перехватывает загрузку изображений и автоматически генерирует AVIF-версию. Если интересна тема ускорения именно Bitrix — смотри мою статью про настройку кеширования в Битрикс.

Squoosh CLI и sharp

Если работаешь с Node.js-стеком, sharp — это твой выбор. Очень быстрый, основан на libvips, отличная документация:

const sharp = require('sharp');
const path = require('path');
const fs = require('fs');

async function convertToAvif(inputPath) {
    const outputPath = inputPath.replace(/\.(jpg|jpeg|png|webp)$/i, '.avif');
    
    await sharp(inputPath)
        .avif({
            quality: 70,
            effort: 4,       // 0-9, аналог speed в avifenc
            chromaSubsampling: '4:2:0'
        })
        .toFile(outputPath);
    
    const inputSize = fs.statSync(inputPath).size;
    const outputSize = fs.statSync(outputPath).size;
    const savings = ((1 - outputSize / inputSize) * 100).toFixed(1);
    
    console.log(`${path.basename(inputPath)}: ${savings}% экономии`);
}

// Запуск
convertToAvif('/var/www/site/images/product-hero.jpg');

Параметр effort в sharp — от 0 до 9 (в отличие от avifenc, где всё наоборот). Я обычно ставлю 4 для баланса скорость/размер. На больших батчах разница между effort 4 и effort 9 по времени может быть в 5-10 раз при экономии в размере всего 5-8%.

Настройка Nginx для отдачи AVIF

Это, честно говоря, самая важная часть. Мало сконвертировать изображения — нужно правильно настроить сервер, чтобы он отдавал AVIF тем, кто его поддерживает, и JPEG/WebP всем остальным.

Стандартный подход — через заголовок Accept в запросе браузера. Когда Chrome запрашивает изображение, он отправляет что-то вроде Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8. Nginx это видит и может отдать нужный формат.

http {
    # Добавляем AVIF MIME-тип
    types {
        image/avif avif;
        image/webp webp;
    }
    
    # Маппинг для выбора формата
    map $http_accept $webp_suffix {
        default        "";
        "~*image/avif" ".avif";
        "~*image/webp" ".webp";
    }
}

server {
    listen 80;
    server_name example.com;
    root /var/www/site;
    
    location ~* \.(jpg|jpeg|png)$ {
        # Пробуем AVIF, потом WebP, потом оригинал
        add_header Vary Accept;
        add_header Cache-Control "public, max-age=31536000";
        
        try_files $uri$webp_suffix $uri =404;
    }
}

Но это упрощённая версия. На практике маппинг работает не идеально — если браузер поддерживает и AVIF, и WebP, переменная $webp_suffix примет значение .avif (первое совпадение). Это правильно, но нужно убедиться, что у тебя реально есть все AVIF-файлы на диске. Если файла нет, try_files упадёт на оригинал — это нормальное поведение.

Более продвинутая конфигурация с отдельными маппингами:

map $http_accept $img_suffix {
    default   "";
    ~image/avif  ".avif";
}

map $http_accept $img_suffix_fallback {
    default   "";
    ~image/webp  ".webp";
}

server {
    location ~* ^(.+)\.(jpe?g|png)$ {
        set $img_base $1;
        set $img_ext  $2;
        
        add_header Vary "Accept";
        expires 1y;
        add_header Cache-Control "public, immutable";
        
        # AVIF → WebP → оригинал
        try_files 
            ${img_base}${img_suffix}.${img_ext}
            ${img_base}${img_suffix_fallback}.${img_ext}
            $uri
            =404;
    }
}
⚠️
Важно про Vary: Accept: Обязательно добавляй заголовок Vary: Accept при такой схеме. Без него CDN и прокси-серверы будут кешировать один формат и отдавать его всем — и тем, кто поддерживает AVIF, и тем, кто не поддерживает. Я видел этот баг у нескольких клиентов — Chrome получал WebP, а Safari — AVIF, который не мог отобразить (это было на старых версиях Safari до 16.4).

Настройка Apache и .htaccess

Если у тебя Apache (например, на shared-хостинге), конфигурация немного другая. Многие мои WordPress-клиенты сидят именно на Apache, поэтому эта секция актуальна.

# .htaccess в корне сайта или в папке с изображениями

<IfModule mod_rewrite.c>
    RewriteEngine On
    
    # Добавляем AVIF MIME-тип
    AddType image/avif .avif
    AddType image/webp .webp
    
    # Проверяем поддержку AVIF
    RewriteCond %{HTTP_ACCEPT} image/avif
    RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png)$
    RewriteCond %1.avif -f
    RewriteRule (.*)\.(jpe?g|png)$ $1.avif [T=image/avif,E=avif:1,L]
    
    # Fallback на WebP
    RewriteCond %{ENV:avif} !1
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png)$
    RewriteCond %1.webp -f
    RewriteRule (.*)\.(jpe?g|png)$ $1.webp [T=image/webp,L]
</IfModule>

# Заголовок Vary
<IfModule mod_headers.c>
    <FilesMatch "\.(jpe?g|png|avif|webp)$">
        Header append Vary Accept
    </FilesMatch>
</IfModule>

Честно говоря, на Apache это работает немного медленнее из-за обработки .htaccess на каждый запрос. Если есть возможность перейти на Nginx — переходи. Но для небольших сайтов разница незаметна. Тема оптимизации доставки файлов вообще гораздо шире — рекомендую почитать статью про настройку сжатия Gzip и Brotli, там много пересекающихся моментов.

AVIF в WordPress: плагины и ручная настройка

WordPress умеет генерировать AVIF начиная с версии 6.5 — там добавили нативную поддержку через Imagick. Но есть нюансы. Imagick должен быть собран с поддержкой libheif, а libheif должен быть собран с поддержкой libaom. На практике это работает не на всех хостингах.

Проверить можно так:

<?php
// Проверяем поддержку AVIF в Imagick
if (class_exists('Imagick')) {
    $formats = Imagick::queryFormats();
    $avif_supported = in_array('AVIF', $formats);
    echo $avif_supported ? 'AVIF поддерживается' : 'AVIF не поддерживается';
    
    // Дополнительно проверяем через GD (PHP 8.1+)
    if (function_exists('imageavif')) {
        echo "\nGD поддерживает AVIF";
    }
}
?>

Если Imagick не поддерживает AVIF, но поддерживает GD (PHP 8.1+), WordPress всё равно будет генерировать AVIF, просто через другую библиотеку. GD работает несколько медленнее и даёт чуть худшее сжатие, но это лучше, чем ничего.

Плагины для AVIF в WordPress

Из плагинов я рекомендую несколько вариантов в зависимости от бюджета и задачи:

Для серьёзных проектов я не полагаюсь на плагины и настраиваю конвертацию на уровне сервера. Плагины — это удобно, но они добавляют нагрузку при загрузке медиа и иногда генерируют AVIF с субоптимальными настройками. Если тебе нужна комплексная работа по ускорению WordPress — загляни на страницу поддержки WordPress.

AVIF в Битрикс: что и как

С Битриксом история отдельная. Встроенной поддержки AVIF в Битрикс нет — они до сих пор работают через GD и Imagick для ресайза, но о AVIF в ядре речи не идёт (по крайней мере, на момент написания статьи). Поэтому подход другой.

Первый вариант — предконвертация всего каталога изображений и настройка Nginx на уровне сервера (описал выше). Битрикс отдаёт ссылку на product.jpg, Nginx видит, что есть product.avif, и отдаёт его браузеру с поддержкой AVIF. Сайт об этом вообще не знает. Самый чистый подход.

Второй вариант — написать обработчик события OnBeforeFileAdd или OnAfterFileAdd, который при загрузке нового изображения запускает конвертацию в фоне через агент или очередь задач. Я делал такое для одного крупного дистрибьютора — у них ежедневно загружалось 200-500 новых изображений товаров.

<?php
// /local/php_interface/init.php

// Агент для конвертации изображений в AVIF
function ConvertNewImagesToAvif(): string
{
    $cacheFile = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/tmp/avif_last_id.txt';
    $lastId = (int)file_get_contents($cacheFile);
    
    $result = \CFile::GetList(
        ['ID' => 'ASC'],
        [
            '>ID' => $lastId,
            'CONTENT_TYPE' => 'image',
        ]
    );
    
    $processed = 0;
    while ($file = $result->Fetch()) {
        $srcPath = $_SERVER['DOCUMENT_ROOT'] . $file['SRC'];
        $avifPath = preg_replace('/\.(jpe?g|png)$/i', '.avif', $srcPath);
        
        if (!file_exists($avifPath) && file_exists($srcPath)) {
            $cmd = sprintf(
                'avifenc --min 20 --max 35 --speed 6 %s %s 2>/dev/null',
                escapeshellarg($srcPath),
                escapeshellarg($avifPath)
            );
            exec($cmd);
            $processed++;
        }
        
        $lastId = (int)$file['ID'];
        
        // Обрабатываем не более 20 файлов за один запуск агента
        if ($processed >= 20) break;
    }
    
    file_put_contents($cacheFile, $lastId);
    
    return 'ConvertNewImagesToAvif();';
}
?>

Агент регистрируется в админке Битрикс или через код при установке модуля. Запускается каждые 5-10 минут, обрабатывает новые файлы пачками по 20 штук. Медленно, но надёжно и без нагрузки на сервер.

💡
Совет по Битрикс: Если у тебя большой каталог и нужна первоначальная массовая конвертация — запускай её через cron в ночное время, а не через веб-интерфейс. Команда типа find /var/www/bitrix/upload -name "*.jpg" -exec avifenc --speed 8 {} {}.avif \; на 50 000 файлах может работать несколько часов. PHP из браузера до этого не доживёт.

AVIF в HTML: правильная разметка с fallback

Это то, о чём многие забывают. Даже если ты настроил сервер правильно, в HTML всё равно стоит использовать правильную разметку — особенно для изображений, которые прописаны напрямую в шаблоне, а не через CMS.

Элемент <picture> с несколькими источниками — стандартный подход:

<!-- Правильная разметка с каскадом форматов -->
<picture>
    <source 
        srcset="/images/hero.avif 1x, /images/hero@2x.avif 2x" 
        type="image/avif">
    <source 
        srcset="/images/hero.webp 1x, /images/hero@2x.webp 2x" 
        type="image/webp">
    <img 
        src="/images/hero.jpg" 
        srcset="/images/hero@2x.jpg 2x"
        alt="Описание изображения"
        width="1200" 
        height="630"
        loading="lazy"
        decoding="async">
</picture>

<!-- Для адаптивных изображений с разными размерами -->
<picture>
    <source 
        media="(max-width: 768px)"
        srcset="/images/product-mobile.avif"
        type="image/avif">
    <source 
        media="(max-width: 768px)"
        srcset="/images/product-mobile.webp"
        type="image/webp">
    <source 
        srcset="/images/product-desktop.avif"
        type="image/avif">
    <source 
        srcset="/images/product-desktop.webp"
        type="image/webp">
    <img 
        src="/images/product-desktop.jpg" 
        alt="Название продукта"
        width="800"
        height="600"
        loading="lazy">
</picture>

Обязательно указывай width и height — это влияет на CLS (Cumulative Layout Shift) в Core Web Vitals. Браузер резервирует место под изображение до его загрузки и не прыгает контент. Подробнее про все метрики производительности — в статье Core Web Vitals: как улучшить показатели.

Атрибут loading="lazy" тоже обязателен для всего, что не в первом экране. И decoding="async" — чтобы декодирование изображения не блокировало основной поток рендеринга.

AVIF в CSS: фоновые изображения

С фоновыми изображениями в CSS сложнее — там нет элемента <picture>. Есть несколько подходов.

Первый — через JavaScript, определяем поддержку и добавляем класс к <html>:

// Определение поддержки AVIF
async function checkAvifSupport() {
    return new Promise((resolve) => {
        const img = new Image();
        img.onload = () => resolve(img.width === 1);
        img.onerror = () => resolve(false);
        // Минимальный валидный AVIF в base64
        img.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAABcAAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAAB9tZGF0EgAKCBgABogQEDQgAGQAAABMiIE=';
    });
}

checkAvifSupport().then(supported => {
    document.documentElement.classList.add(supported ? 'avif' : 'no-avif');
});

Потом в CSS:

/* Базовый стиль (JPEG) */
.hero-banner {
    background-image: url('/images/hero-bg.jpg');
}

/* AVIF для поддерживающих браузеров */
.avif .hero-banner {
    background-image: url('/images/hero-bg.avif');
}

/* WebP как промежуточный вариант */
.no-avif .hero-banner {
    background-image: url('/images/hero-bg.webp');
}

Второй подход — через image-set() в CSS (поддерживается современными браузерами):

.hero-banner {
    background-image: image-set(
        url('/images/hero-bg.avif') type('image/avif'),
        url('/images/hero-bg.webp') type('image/webp'),
        url('/images/hero-bg.jpg') type('image/jpeg')
    );
}

Грубо говоря, image-set() — это <picture> для CSS. Браузер выберет первый поддерживаемый формат. Поддержка хорошая в 2026 году, но для максимальной совместимости я всё равно дублирую fallback через JS-класс.

Мониторинг результатов и реальные цифры

После внедрения AVIF обязательно нужно измерить результат. Я смотрю на несколько метрик.

PageSpeed Insights / Lighthouse. Смотрю на "Serve images in next-gen formats" — этот аудит должен исчезнуть или показывать минимальное потенциальное сбережение. Также смотрю на LCP (Largest Contentful Paint) — если главная картинка была JPEG, после перехода на AVIF LCP обычно улучшается на 15-30%.

Трафик на сервере. После полного перехода на AVIF у одного e-commerce клиента (около 50 000 посетителей в месяц) исходящий трафик с сервера снизился с 180 GB до 65 GB в месяц. Это прямая экономия на тарифе хостинга и CDN.

Время загрузки страниц. Через Яндекс.Метрику (Вебвизор + отчёт по скорости) или Google Analytics 4 (Web Vitals). После AVIF среднее время загрузки страниц каталога у того же клиента упало с 4.2 секунды до 2.1 секунды на мобильных устройствах.

Если хочешь глубже погрузиться в тему производительности и измерений — очень рекомендую статью Google PageSpeed Insights 2026: улучшаем оценку сайта, там подробно про все метрики и как их трактовать.

Ещё один момент: не забывай про CDN. Если ты используешь CDN (Cloudflare, BunnyCDN, или другой), убедись, что он правильно кеширует разные форматы для разных браузеров. Cloudflare, например, имеет встроенную функцию Polish — она автоматически конвертирует изображения в WebP или AVIF прямо на уровне CDN. Это отдельная тема, подробнее — в руководстве по настройке CDN для сайта.

⚠️
Про скорость кодирования: AVIF кодируется значительно медленнее, чем JPEG или WebP. На слабых серверах (VPS с 1-2 CPU) массовая конвертация 10 000 изображений с effort=6 может занять несколько часов. Не запускай это в пиковое время. И никогда не конвертируй AVIF "на лету" при первом обращении — только предварительно или в фоне.

Частые ошибки при внедрении AVIF

За время работы с AVIF я набил несколько шишек, которые хочу тебе помочь избежать.

Ошибка 1: Конвертировать PNG с прозрачностью в AVIF без проверки. AVIF поддерживает альфа-канал, но некоторые старые версии libavif обрабатывали прозрачность с артефактами. Всегда проверяй результат визуально — особенно на PNG с тонкими краями и полупрозрачностью.

Ошибка 2: Забыть про MIME-тип. Если сервер не знает о MIME-типе image/avif, браузер может отказаться отображать файл. Всегда добавляй AddType image/avif .avif в Apache или соответствующую строку в nginx types. Я видел эту проблему на нескольких shared-хостингах — приходилось добавлять в .htaccess.

Ошибка 3: Не обновлять sitemap. Если у тебя в XML sitemap прописаны изображения (image:image), там нужно оставить ссылки на оригинальные JPEG/PNG — поисковики пока не индексируют AVIF напрямую. Это не проблема, просто нужно помнить.

Ошибка 4: Слишком агрессивное сжатие. Я видел сайты, где AVIF выглядит хуже оригинального JPEG. Это значит, что качество выставлено слишком низко (высокие значения min/max в avifenc). Для фотографий я рекомендую min=20, max=35. Для скриншотов и графики с текстом — min=10, max=25.

Ошибка 5: Игнорировать анимированные изображения. GIF и анимированные PNG тоже можно конвертировать в AVIF (анимированный). Экономия огромная. Но поддержка анимированного AVIF в браузерах чуть хуже, поэтому для анимации я делаю fallback на WebP-анимацию, а не на GIF.

Комплексная оптимизация изображений — это не только формат. Это ещё lazy loading, правильные размеры, предзагрузка критических изображений. Всё это влияет на итоговый результат, и если хочешь разобраться в теме глубже — рекомендую почитать про Lazy Loading изображений.

По опыту могу сказать: AVIF — это одно из немногих технических улучшений, где соотношение затрат к результату просто отличное. Один раз настроил конвертацию и отдачу, и сайт стал быстрее без каких-либо изменений в коде или логике. Если нужна помощь с настройкой на конкретном проекте — обращайся через страницу доработки сайта, разберёмся.

Хотите ускорить загрузку сайта с помощью AVIF?

Мы настроим современные форматы изображений и оптимизируем ваш сайт для максимальной скорости и высоких позиций в поиске.

П
Павел
Веб-разработчик · 10+ лет опыта · Bitrix, WordPress, Laravel

Читайте также

Настройка Elasticsearch для сайта: быстрый поиск в 2026 Настройка автоматического резервного копирования сайтов 2026 Как выбрать хостинг для сайта: на что обратить внимание