digital-garden/knowledge/dev/snippet/Оптимизация изображений.md

4.1 KiB
Raw Permalink Blame History

tags date zero-link parents linked
зрелость/🌱
2023-11-20
../../../garden/ru/meta/zero/00 Разработка

Размер изображений составляет существенную часть от размера страницы. Вот уже второй день вожусь с оптимизацией изображений в блоге. До этого я использовал скрипт, который позволяет сжать jpg и png без потерь.

Теперь решил пойти еще дальше и использовать Webp формат.

WebP - это формат сжатия изображений, разработанный компанией Google. Он использует современный алгоритм сжатия, который обеспечивает более эффективное сжатие, чем форматы JPEG и PNG, что может привести к быстрее загрузке веб-страниц и экономии интернет-трафика.

В итоге пришел к такому кейсу:

  1. Прогоняю скриптом сжатия без потерь.
  2. Прогоняю скриптом для преобразования в webp. Сохраняю все изображения в отдельную папку.
  3. Nginx пытается сначала найти webp изображение, если не получается, то берет сжатый png или jpg

А вот и сам скрипт для преобразования в webp:

#!/bin/bash
file=webp.flag

if [ -f "$file" ]; then
  option="-newer $file"
fi

find ./struchkov.dev/www/images/ -type f -iregex '.*\.\(jpg\|jpeg\|png\)' $option -exec sh -c '
  webp_file="${1/\/images\//\/images\/webp\/}"
  webp_dir="$(dirname "$webp_file")"
  mkdir -p "$webp_dir"
  cwebp -mt -af -progress -m 6 -q 85 -pass 10 "$1" -o "${webp_file%.*}.webp"
' _ {} \;

touch "$file"
echo "$(date)" > "$file"

Также как и в первом скрипте, я использую файл-флаг, чтобы не преобразовывать файлы, которые уже преобразовывались.

Далее я беру папку /struchkov.dev/www/images/, в которой лежат исходные изображения и создаю новую папку /struchkov.dev/www/images/webp. Внутри папки webp структура папок и файлов такая же, как и в папке images. Только формат у файлов .webp.

За преобразование отвечает команда cwebp. Эта утилита сжимает изображения, но с потерями в качестве. Я подобрал оптимальные параметры сжатия, чтобы потеря качества была не заметна, но при этом изображения занимали меньше места.

cwebp -mt -af -progress -m 6 -q 85 -pass 10 "$1" -o "${webp_file%.*}.webp"

Подробнее об этих и других параметрах можно почитать в документации.

Nginx

Теперь сделаем так, чтобы при запросе jpg/png изображения отдавался аналогичный webp файл. Для этого в конфигурацию nginx добавляем:

location ~* ^(/blog/ru/content/images/)(.+)\.(png|jpe?g)$ {	
    expires max;
    alias /var/struchkov.dev/ghost/www/images;
    set $webp_image_subdir "/webp/";
    set $basename $2;
    try_files $webp_image_subdir$basename$webp_suffix $uri;
}

try_files сначала попытается достать webp изображение, если его нет, то возьмет сжатый оригинал формата jpg/png.