Оптимизатор картинок для сайта

Современные форматы сжатых изображений стали достаточно хороши для того, чтобы вытеснить традиционный JPEG. Внедрять их в дело с помощью разнообразных плагинов и уж тем более внешних сервисов желания не возникает как в силу замороченности и полуплатности плагинов, так и в силу неудобных алгоритмов их работы. Без вмешательства в работу сайта оно как-то логичнее.

Написал скриптик по изготовлению кэша с конвертированными в форматы WEBP и AVIF файлами:

#! /bin/bash

############################################################
##                                                        ##
##  Конвертация картинок сайта в более экономные форматы  ##
##  v 1.1                                                 ##
##  2024-02-23                                            ##
##                                                        ##
############################################################


##  Планируемые доработки:
##  1. Сделать обратную конвертацию в jpeg для webp и avif 
##  файлов в целях совместимости со старыми браузерами

# Путь к папке сайта с исходными картинками (вложенные папки перенесутся автоматически)

SOURCE_DIR='<путь к папке>/uploads';

# Путь к папке кэша с набором конвертированных картинок

TARGET_DIR='<путь к папке>/cache';

cd $SOURCE_DIR;

# Ищем в исходной папке файлы под конвертацию
ARRAY=()
while read FILE; do
    ARRAY+=("${FILE%$SUFFIX}")
done < <(find . -type f -regextype posix-egrep -regex "^.*(.jpg|.jpeg|.png|.gif)$" -mtime -1)

for ITEM in "${ARRAY[@]}"; do
	LOCALPATH="${ITEM:1}"
	SUFFIX="${LOCALPATH##*.}"
	NAME=${LOCALPATH%%.*}
    SOURCE_FILE="$SOURCE_DIR$LOCALPATH"
    echo " "
    if [ -f  "$SOURCE_FILE" ]; then
	    z=$(stat -c '%s' "$SOURCE_FILE")
	    echo "├── $z $SOURCE_FILE"
	    if [[ $SUFFIX =~ ^(jpg|jpeg|png|gif)$ ]]; then
	    	TARGET_FILE="$TARGET_DIR$NAME.webp"
	    	# поверяем наличие папки в кэше и создаём если её нет
	    	if [ ! -d $(dirname "$TARGET_FILE") ]; then
	    		mkdir -p $(dirname "$TARGET_FILE")
	    	fi
	    	if [ ! -f  $TARGET_FILE ]; then
	    		convert $SOURCE_FILE $TARGET_FILE
	    	else
	    		echo "├── Файл webp уже есть"
	    	fi

	   		z=$(stat -c '%s' "$TARGET_FILE")
			echo "├── $z $TARGET_FILE"

	    	if [[ $SUFFIX =~ ^(jpg|jpeg)$ ]]; then
			    TARGET_FILE="$TARGET_DIR$NAME.avif"
			    if [ ! -f  $TARGET_FILE ]; then
			    	convert $SOURCE_FILE $TARGET_FILE
			    else
			    	echo "├── Файл avif уже есть"
			    fi
		   		z=$(stat -c '%s' "$TARGET_FILE")
				echo "├── $z $TARGET_FILE"
			fi
	    else
	    	echo "├── пропускаем";
	    fi
	fi
done

Первый раз прогнал его, подправив в поиске время на -mmin +300, а в дальнейшем поставил в крон раз в сутки.

После этого, осталось только внести изменения в настройки веб-сервера Angie (для Nginx всё идентично в данном случае)

     # раздача статики   
     location ~ \.(css|js|gif|webp|avif|jpg|jpeg|jpe|asf|asx|wax|wmv|wmx|avi|avifs|bmp|class|divx|doc|docx|exe|gz|gzip|ico|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|webm|mpp|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|_ttf|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip|ttf|woff|woff2|eot)$ {
            
            expires 300d;
            etag on;
            if_modified_since exact;
            add_header Pragma "public";
            add_header Cache-Control "public";
            add_header Referrer-Policy "no-referrer-when-downgrade";

            # список расширений должен совпадать со списком в скрипте-обработчике
            location ~* ^/wp-content/uploads(?<path>.+)\.(jpe?g|png|gif)$ {               
                add_header Vary Accept;
                try_files /<путь к папке>/cache${path}.avif /<путь к папке>/cache{path}.webp $uri /index.php?$args;
            }
            # необходима для избежания зацикливания в try_files предыдущей location
            location /<путь к папке>/cache {               
                add_header Vary Accept;
            }

            try_files $uri $uri/ /index.php?$args;
        }

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

Минусы: конвертированные копии файлов занимают некоторое место.

Добавить комментарий