Как уменьшить на сайте размер занимаемый картинками?
Предыстория. Вы создали сайт на WordPress и он прекрасно развивается растёт — всё хорошо. Но! Через пару лет вы замечаете, что резервная копия, а вы ведь периодически создаёте такой backup сайта на всякий случай, мало ли) так вот вы видите что размер резервной копии сайта более 2,3 или даже 4 и более гигабайт! Что делать? Тут многие админы сайтов уже за годы эксплуатации своего интернет проекта начинают устанавливать всякие плагины по оптимизации изображений и прочую всякую ерунду толку от которой практически нет, но зато есть много геморроя)
Я предлагаю простое решение. Все современные сайты, а именно так должно быть для сайтов наших дней — находятся на VPS (выделенный виртуальный сервер). По цене VPS стоит сейчас примерно так же как обычный виртуальный план, но за то это свобода, мощь и независимость от других проектов размещённых на одном ip как это принято на обычных виртуальных тарифных планах почти всех существующих хостинг компаний. На VPS вся мощь сервера принадлежит только вашему интернет проекту — простая регистрация и аккаунт готов к работе. Как установить программное обеспечение и настроить сервер? Я рекомендую чтобы в начале не заморачиваться с работой в терминале — установить простые и популярные бесплатные панели управления сервером:
Какую выбрать? Мне в последние годы интереснее OpenLiteSpeed — почему? Вот сравнение современных систем (ссылка без VPN может не открыться). Вот основное в картинках из материала:

OpenLiteSpeed vs Apache

OpenLiteSpeed vs Apache
Вернёмся к теме статьи. И так как же оптимизировать картинки на сайте. И так вы современный юзер и ваш сайт на VPS если ещё нет то желательно это сделать, повторюсь стоит так же а плюсов в разы больше. Раз вы на VPS то подключаетесь по ssh к серверу:
ssh root@89.93.131.146
и в следующей строке пароль (копируете его и вставляете нажатием правой кнопки мыши, визуально ничего не произойдёт, потом Enter)
я использую стандартную программу на Windows это «Windows Power Shell»
Далее пошаговое действие и да у меня все картинки были в формате .jpeg и .jpg
nano /root/optimize_jpg_uploads.sh
откроется пустое содержание, вводите туда следующий скрипт, вставь полностью:
#!/bin/bash
BASE_DIR="/var/www/ruistat_22/data/www/ruistat.ru/wp-content/uploads"
LOG_FILE="/root/jpg_optimize.log"
MIN_SIZE=153600 # 150 KB
echo "=== JPG optimization started $(date) ===" >> "$LOG_FILE"
find "$BASE_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -size +${MIN_SIZE}c -print0 |
while IFS= read -r -d '' file; do
SIZE_BEFORE=$(stat -c%s "$file")
jpegoptim \
--strip-all \
--max=82 \
--all-progressive \
"$file" >> "$LOG_FILE" 2>&1
SIZE_AFTER=$(stat -c%s "$file")
if [ "$SIZE_AFTER" -lt "$SIZE_BEFORE" ]; then
SAVED=$((SIZE_BEFORE - SIZE_AFTER))
echo "OK: $file | saved $SAVED bytes" >> "$LOG_FILE"
else
echo "SKIP: $file | no gain" >> "$LOG_FILE"
fi
done
echo "=== JPG optimization finished $(date) ===" >> "$LOG_FILE"
где надо изменить лишь эту строку:
BASE_DIR="/var/www/ruistat_22/data/www/ruistat.ru/wp-content/uploads"
это путь до папки с картинками и он будет у вас свой. Чтобы узнать какой он этот свой путь — откройте файловый в панели управления сервером Fastpanel или OpenLiteSpeed и пройдите до папки /uploads/ — это и будет ваш путь который надо вставить в скрипт который я привёл выше.
Далее нажимаете в английской раскладке клавиатуры CTRL O далее жмёте на кнопку ENTER и далее CTRL X
Такими действиями вы сохраните внесённые изменения в создаваемый скрипт. Уточню что здесь CTRL O буква O в английской раскладке.
Потом устанавливаете права
chmod +x /root/optimize_jpg_uploads.sh
Чтобы сперва посчитать сколько было гб и сколько станет после оптимизации картинок на сайте используйте эту команду:
du -sh /var/www/ruistat_22/data/www/ruistat.ru/wp-content/uploads
тут же получите ответ в терминале, далее оптимизация:
nohup /root/optimize_jpg_uploads.sh > /root/jpg_optimize_nohup.log 2>&1 &
Чтобы понять когда процесс завершиться я тут же запускаю команду отслеживающую нагрузку на сервере в реальном времени:
top
и в первых строках увидите такой процесс:
jpegoptim
этот процесс будет то появляться то пропадать и через пару минут (у меня на 3 гб ушло времени меньше 1 минуты на всю оптимизацию)
вы увидите 
и перестанет выскакивать процесс:
jpegoptim
это значит оптимизация прошла, и прошла успешно! Запускайте такую команду (не забудьте указывать в командах свои данные домена и правильный путь)
du -sh /var/www/ruistat_22/data/www/ruistat.ru/wp-content/uploads
чтобы увидеть новый оптимизированный размер папки где храняться ваши картинки сайта.
У меня за счёт оптимизации картинок на сайте размер резервной копии уменьшился более чем в два раза.

Напомню что запуск возможен только от root (запуск возможен только у того, у кого есть root/sudo) и скрипт лежит в /root/ это означает: каталог /root доступен только пользователю root другие пользователи туда даже с cd не смогут попасть, права на файл даже если файл chmod +x без доступа к /root — недостижим, права на файлы WordPress /var/www/…/uploads обычно принадлежат www-data, но root может писать везде, а обычный пользователь — нет (если явно не разрешено).
Что будет, если другой пользователь попробует запустить скрипт. Permission denied — что переводится, как «в разрешении отказано»
Выбрать хостинг
Попробуйте расширить скрипт и на другие форматы: PNG и WebP они потребуют другого подхода и инструментов, но это вполне реализуемо. Вот обновлённый код на основе Вашего примера.
Сначала нужно установить необходимые утилиты:
Потом проверить что всё встало правильно на сервер
Вот обновленная версия кода:
#!/bin/bash # --- НАСТРОЙКИ --- BASE_DIR="/var/www/b2bq_ru_usr/data/www/b2bq.ru/wp-content/uploads" LOG_FILE="/root/all_images_optimize.log" MIN_SIZE_JPG=153600 # 150 KB для JPG/JPEG MIN_SIZE_PNG=102400 # 100 KB для PNG MIN_SIZE_WEBP=102400 # 100 KB для WebP # --- СЧЁТЧИКИ ДЛЯ СТАТИСТИКИ --- TOTAL_JPG=0 TOTAL_PNG=0 TOTAL_WEBP=0 OPTIMIZED_JPG=0 OPTIMIZED_PNG=0 OPTIMIZED_WEBP=0 FAILED_JPG=0 FAILED_PNG=0 FAILED_WEBP=0 # Функция для записи в лог с выводом в консоль log() { echo "$1" | tee -a "$LOG_FILE" } # --- 1. ОПТИМИЗАЦИЯ JPG/JPEG --- optimize_jpeg() { local file="$1" local size_before=$(stat -c%s "$file") # Временный файл для безопасной работы local temp_file="${file}.opt.jpg" cp "$file" "$temp_file" jpegoptim --strip-all --max=82 --all-progressive "$temp_file" 2>/dev/null if [ -f "$temp_file" ]; then local size_after=$(stat -c%s "$temp_file") local saved=$((size_before - size_after)) if [ "$size_after" -lt "$size_before" ]; then mv "$temp_file" "$file" log "✅ JPG: $(basename "$file") | $(($size_before/1024))KB → $(($size_after/1024))KB | -$((saved/1024))KB ($(($saved * 100 / $size_before))%)" OPTIMIZED_JPG=$((OPTIMIZED_JPG + 1)) else rm -f "$temp_file" log "⏭️ JPG: $(basename "$file") | $(($size_before/1024))KB | Нет выигрыша" fi else log "⚠️ JPG: $(basename "$file") | Ошибка оптимизации" FAILED_JPG=$((FAILED_JPG + 1)) fi TOTAL_JPG=$((TOTAL_JPG + 1)) } # --- 2. ОПТИМИЗАЦИЯ PNG --- optimize_png() { local file="$1" local size_before=$(stat -c%s "$file") local temp_file="${file}.opt.png" # Копируем оригинал во временный файл cp "$file" "$temp_file" # Шаг 1: optipng (lossless - без потери качества) optipng -o2 -strip all "$temp_file" 2>/dev/null # Шаг 2: pngquant (lossy - с небольшой потерей качества) pngquant --quality=82 --speed=1 --force --output "$temp_file" "$temp_file" 2>/dev/null if [ -f "$temp_file" ]; then local size_after=$(stat -c%s "$temp_file") local saved=$((size_before - size_after)) if [ "$size_after" -lt "$size_before" ]; then mv "$temp_file" "$file" log "✅ PNG: $(basename "$file") | $(($size_before/1024))KB → $(($size_after/1024))KB | -$((saved/1024))KB ($(($saved * 100 / $size_before))%)" OPTIMIZED_PNG=$((OPTIMIZED_PNG + 1)) else rm -f "$temp_file" log "⏭️ PNG: $(basename "$file") | $(($size_before/1024))KB | Нет выигрыша" fi else log "⚠️ PNG: $(basename "$file") | Ошибка оптимизации" FAILED_PNG=$((FAILED_PNG + 1)) fi TOTAL_PNG=$((TOTAL_PNG + 1)) } # --- 3. ОПТИМИЗАЦИЯ WEBP --- optimize_webp() { local file="$1" local size_before=$(stat -c%s "$file") local temp_file="${file}.opt.webp" # Ключевые опции: -m 6 (макс. сжатие), -q 85 (качество), -pass 10 (больше проходов) cwebp -q 85 -m 6 -pass 10 -mt "$file" -o "$temp_file" 2>/dev/null if [ -f "$temp_file" ]; then local size_after=$(stat -c%s "$temp_file") local saved=$((size_before - size_after)) if [ "$size_after" -lt "$size_before" ]; then mv "$temp_file" "$file" log "✅ WEBP: $(basename "$file") | $(($size_before/1024))KB → $(($size_after/1024))KB | -$((saved/1024))KB ($(($saved * 100 / $size_before))%)" OPTIMIZED_WEBP=$((OPTIMIZED_WEBP + 1)) else rm -f "$temp_file" log "⏭️ WEBP: $(basename "$file") | $(($size_before/1024))KB | Нет выигрыша" fi else log "⚠️ WEBP: $(basename "$file") | Ошибка сжатия (cwebp не доступен?)" FAILED_WEBP=$((FAILED_WEBP + 1)) fi TOTAL_WEBP=$((TOTAL_WEBP + 1)) } # --- ФУНКЦИЯ ПОДСЧЁТА ОБЩЕГО РАЗМЕРА ПАПКИ --- calculate_initial_size() { if [ -d "$BASE_DIR" ]; then local size=$(du -sh "$BASE_DIR" 2>/dev/null | cut -f1) echo "$size" else echo "0" fi } # --- ФУНКЦИЯ ПОДСЧЁТА ФАЙЛОВ ДЛЯ ОБРАБОТКИ --- count_files_to_process() { local jpg_count=$(find "$BASE_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -size +${MIN_SIZE_JPG}c 2>/dev/null | wc -l) local png_count=$(find "$BASE_DIR" -type f -iname "*.png" -size +${MIN_SIZE_PNG}c 2>/dev/null | wc -l) local webp_count=$(find "$BASE_DIR" -type f -iname "*.webp" -size +${MIN_SIZE_WEBP}c 2>/dev/null | wc -l) echo "$jpg_count $png_count $webp_count" } # --- ОСНОВНОЙ ЗАПУСК --- START_TIME=$(date +%s) log "=========================================" log "=== МУЛЬТИФОРМАТНАЯ ОПТИМИЗАЦИЯ СТАРТОВАНА ===" log "Дата и время: $(date)" log "=========================================" # Проверка существования базовой директории if [ ! -d "$BASE_DIR" ]; then log "❌ ОШИБКА: Директория $BASE_DIR не существует!" exit 1 fi # Проверка наличия необходимых утилит MISSING_TOOLS="" for tool in jpegoptim optipng pngquant cwebp; do if ! command -v $tool &> /dev/null; then MISSING_TOOLS="$MISSING_TOOLS $tool" fi done if [ ! -z "$MISSING_TOOLS" ]; then log "⚠️ ВНИМАНИЕ: Отсутствуют следующие утилиты:$MISSING_TOOLS" log "Установите их командой: apt-get install jpegoptim optipng pngquant webp -y" log "Продолжение может быть невозможным для некоторых форматов." fi # Информация о начале работы INITIAL_SIZE=$(calculate_initial_size) log "📁 Директория: $BASE_DIR" log "💾 Текущий размер: $INITIAL_SIZE" log "" log "🔍 Подсчёт файлов для обработки..." # Подсчёт файлов read JPG_COUNT PNG_COUNT WEBP_COUNT <<< $(count_files_to_process) log "📊 Найдено файлов больше минимального размера:" log " JPG/JPEG (>$(($MIN_SIZE_JPG/1024))KB): $JPG_COUNT шт." log " PNG (>$(($MIN_SIZE_PNG/1024))KB): $PNG_COUNT шт." log " WEBP (>$(($MIN_SIZE_WEBP/1024))KB): $WEBP_COUNT шт." log "" # Обработка JPG/JPEG if [ $JPG_COUNT -gt 0 ]; then log "🔧 НАЧАЛО ОБРАБОТКИ JPG/JPEG (всего: $JPG_COUNT файлов)..." find "$BASE_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -size +${MIN_SIZE_JPG}c -print0 | while IFS= read -r -d '' file; do optimize_jpeg "$file" done log "✅ JPG/JPEG обработано: $OPTIMIZED_JPG из $TOTAL_JPG оптимизировано, пропущено: $(($TOTAL_JPG - $OPTIMIZED_JPG - $FAILED_JPG)), ошибок: $FAILED_JPG" log "" else log "⏭️ JPG/JPEG: нет файлов больше $(($MIN_SIZE_JPG/1024))KB для обработки" fi # Обработка PNG if [ $PNG_COUNT -gt 0 ]; then log "🔧 НАЧАЛО ОБРАБОТКИ PNG (всего: $PNG_COUNT файлов)..." find "$BASE_DIR" -type f -iname "*.png" -size +${MIN_SIZE_PNG}c -print0 | while IFS= read -r -d '' file; do optimize_png "$file" done log "✅ PNG обработано: $OPTIMIZED_PNG из $TOTAL_PNG оптимизировано, пропущено: $(($TOTAL_PNG - $OPTIMIZED_PNG - $FAILED_PNG)), ошибок: $FAILED_PNG" log "" else log "⏭️ PNG: нет файлов больше $(($MIN_SIZE_PNG/1024))KB для обработки" fi # Обработка WEBP if [ $WEBP_COUNT -gt 0 ]; then log "🔧 НАЧАЛО ОБРАБОТКИ WEBP (всего: $WEBP_COUNT файлов)..." find "$BASE_DIR" -type f -iname "*.webp" -size +${MIN_SIZE_WEBP}c -print0 | while IFS= read -r -d '' file; do optimize_webp "$file" done log "✅ WEBP обработано: $OPTIMIZED_WEBP из $TOTAL_WEBP оптимизировано, пропущено: $(($TOTAL_WEBP - $OPTIMIZED_WEBP - $FAILED_WEBP)), ошибок: $FAILED_WEBP" log "" else log "⏭️ WEBP: нет файлов больше $(($MIN_SIZE_WEBP/1024))KB для обработки" fi # ИТОГОВАЯ СТАТИСТИКА END_TIME=$(date +%s) DURATION=$((END_TIME - START_TIME)) HOURS=$((DURATION / 3600)) MINUTES=$(((DURATION % 3600) / 60)) SECONDS=$((DURATION % 60)) FINAL_SIZE=$(calculate_initial_size) log "=========================================" log "=== ОПТИМИЗАЦИЯ ЗАВЕРШЕНА ===" log "Время выполнения: ${HOURS}ч ${MINUTES}м ${SECONDS}с" log "Дата и время окончания: $(date)" log "=========================================" log "📊 ИТОГОВАЯ СТАТИСТИКА:" log " JPG: обработано $TOTAL_JPG, оптимизировано $OPTIMIZED_JPG" log " PNG: обработано $TOTAL_PNG, оптимизировано $OPTIMIZED_PNG" log " WEBP: обработано $TOTAL_WEBP, оптимизировано $OPTIMIZED_WEBP" log "=========================================" log "💾 ЭФФЕКТИВНОСТЬ:" log " Размер ДО: $INITIAL_SIZE" log " Размер ПОСЛЕ: $FINAL_SIZE" log "=========================================" # Отправка уведомления (опционально, если настроен mail) # echo "Оптимизация изображений завершена на $(hostname)" | mail -s "Image Optimization Complete" your-email@example.com exit 0В чём улучшение.
1. PNG: Двойное сжатие. Сначала optipng пытается сжать файл без потери качества (lossless) . Он переупаковывает данные, делая файл меньше, но картинка остается идеальной.
Затем pngquant применяет сжатие с потерей качества (lossy) . Уровень качества я поставил 82 (из 100) — это дает отличный баланс. Вы можете изменить / поиграть с параметром —quality.
2. WebP: Пересжатие. Утилита cwebp используется для сжатия существующих WebP-файлов. Это может показаться странным (сжимать уже сжатое), но иногда WebP создаются не совсем оптимально (например, с высоким качеством 100). Параметр -q 85 задает хорошее качество, а -m 6 включает максимальный режим сжатия (процесс может быть медленнее, но результат лучше).
Нажмите Alt+T в nano чтобы всё удалить сразу!