Оптимизация скорости xenForo

Eugenesh

Участник
Регистрация
19 Июл 2019
Сообщения
416
Пол
мужской
Добрый день.

Поделюсь своим опытом по оптимизации изображений xenForo. Есть такой формат картинок WEBP, разработан в Гугле с целью заменить устаревший формат JPEG. Особенность webp - меньший размер файлов по сравнению с jpeg.

Формат поддерживается всеми браузерами на всех платформах кроме iOS и MacOS. Т.е. на более чем 80% браузеров. Формат уже пару лет используют крупные компании Google, Faacebook, Twitter, Yandex и т.д.

Цель перевода изображений форума на новый формат:

1) Скорость отдачи картинок для пользователей повысится, это экономия трафика для пользователей и для сервера. Для мобильных устройств экономится батарея.
2) Google (и возможно Yandex) продвигает этот формат и дает преференции сайтам которые его поддерживают в поисковой выдаче. По моим наблюдениям после перевода сайта на WEBP получилось продвинуться на несколько позиций вверх в поиске Гугла.

Вот скриншот из из каталога автатаров xenForo, по скриншоту можно оценить степень сжатия WEBP по сравнению с JPEG:

filelist.png

Для перевода xenForo на WEBP необходимо создать копии JPEG файлов в формате WEPB. Для этого необходимо установить утилиту convert из пакета ImageMagick

sudo apt-get install imagemagick

И поставить в cron скрипт преобразования картинок. Скрипт можно запускать пару раз в сутки.

Код:
#!/bin/bash

# Путь ко всем изображениям xenForo
XENFORO_IMG_PATH=/var/www/notrink.ru/data

# Путь только к аватарам изображений xenForo
#XENFORO_IMG_PATH=/var/www/notrink.ru/data/avatars

# Качество .webp изображений, 10 - минимальное качество, 100 - максимальное качество, от 70 до 90 - оптимальное качество
WEBP_QUALITY=85

# Отработка сигнала INT после нажатия на клавиатуре Ctrl+C
IS_PROCESSED=1
trap ctrl_c INT
function ctrl_c() {
    IS_PROCESSED=0
}

# Получить список JPEG изображений которые последний раз модифицировались более 5 минут назад
FILE_LIST=`find -L $XENFORO_IMG_PATH -mmin +5 -name "*.jpg"`

# В цикле создать копии файлов из *.jpg в *.webp
for SRC_FILE_PATH in $FILE_LIST; do

    # При нажатии Ctrl+C прекратить работу скрипта
    if [[ "$IS_PROCESSED" == "0" ]]; then
        break
    fi

    # Путь к .webp изображению
    DST_FILE_PATH=$SRC_FILE_PATH.webp

    # Если .webp изображение уже существует, то ничего не делать
    if [ -f $DST_FILE_PATH ]; then
        continue
    fi

    # Конвертировать в .webp при помощи утилиты convert из библиотеки ImageMagick
    echo "Convert $SRC_FILE_PATH to $DST_FILE_PATH"
    convert -filter Lanczos -strip -quality $WEBP_QUALITY $SRC_FILE_PATH $DST_FILE_PATH

    # Назначить владельцем файла пользователя.группу www-data.www-data (для debian дистрибутивов)
    chown www-data.www-data $DST_FILE_PATH

    # Назначить права чтения/записи всех пользователей
    chmod ugo+w $DST_FILE_PATH
done

Потом надо настроить nginx на отдачу WEBP по HTTP HEADER Accept. Основная идея в том, что браузеры поддерживающие формат будут присылать на сервер заголовок Accept: image/webp. По наличию этого заголовка надо отдать копию WEBP изображения. Для остальных браузеров (iOS и macOS) будем отдавать обычный JPEG.

Для этого в файле /etc/nginx/nginx.conf в секции server добавляем такие строки:

Код:
location ~* \.(jpg|jpeg)$ {

        set $is_webp 0;

        # Проверка заголовка Accept и наличия версии файла в .webp.
        if ($http_accept ~* "webp")    { set $is_webp 1; }
        if (-f $request_filename.webp) { set $is_webp 1$is_webp; }

        # Если WebP есть, то передать Vary
        if ($http_accept = "1") {
            add_header Vary Accept;
        }

        # Если клиент поддерживает WebP, то передать файл
        if ($is_webp = "11") {
            rewrite (.*) $1.webp break;
        }
    }
 
Спасибо за предложение. Я посоветуюсь по этому вопросу с программистом, осуществляющим техническую поддержку НД.
 
Ошибся с конфигураций nginx.conf .

HTTP заголовок Vary Accept нужно передавать всегда (особенно критично для сайтов сидящих за прокси типа CDN Cloudflare).

Для этого в файле /etc/nginx/nginx.conf в секции server добавляем такие строки:
Код:
location ~* \.(jpg|jpeg)$ {

        set $is_webp 0;

        # Проверка заголовка Accept и наличия версии файла в .webp.
        if ($http_accept ~* "webp")    { set $is_webp 1; }
        if (-f $request_filename.webp) { set $is_webp 1$is_webp; }

        # Всегда передать Vary Accept для отработки коллизий кеширования прокси-серверами
        add_header Vary Accept;

        # Если клиент поддерживает WebP, то передать файл
        if ($is_webp = "11") {
            rewrite (.*) $1.webp break;
        }
    }
 
Назад
Сверху Снизу