Разработка электроники,

Систем автоматики,

Программного обеспечения

ООО "Антех ПСБ",
Санкт-Петербург

+79811865082

anteh@bk.ru

ООО Антех ПСБ примеры

Автоматическая оптимизация изображений сервера, jpeg png gif html css js. Оптимизация HTML XHTML XML. FreeBSD 9.2

04.04.2015 https://anteh.ru

Для оптимизации jpeg используем jpegoptim, для png OptiPNG, для gif gifsicle, для html tidy-html5, для css js yuicompressor

Jpegoptim обработка jpeg

# cd /usr/ports/graphics/jpegoptim

Устанавливаем jpegoptim-1.4.2

Запускаем оптимизацию всех изображений сайта:

# find /dir/www/site.ru -name "*.jpg" -print0 | xargs -0 jpegoptim --all-progressive --strip-all -ft

--all-progressive - все выходные файлы преобразуются в прогрессивный jpeg
--strip-all - удаляет все маркеры и exif
-f -принудительная оптимизация
-t -выведет строку с результатом оптимизации: "Average compression (160 files): 14.47% (908k)" -результат без флага -f принудительной оптимизации.

После принудительного -f преобразования результат сжатия может быть нулевым "Average compression (160 files): 0.00% (-2k)" но теперь все .jpeg изображения стали progressive jpeg -быстрее будут грузиться

OptiPNG используем для обработки png без потери качества.

# cd /usr/ports/graphics/optipng

Устанавливаем optipng-0.7.4_1

Запуск оптимизации всех .png файлов сайта:

# find /dir/www/site.ru -name "*.png" -print0 | xargs -0 optipng -o7 -strip all -force

-strip all -очистить все поля кроме tRNS
-force -принудительная оптимизация
-o7 -максимальная оптимизация. Занимает много времени
Все опции описаны в optipng -help

При запуске optipng под рутом он меняет владельца .png файлов на root, восстанавливаем:
chown -R user:group /путь имя директории сайта
user:group -соответственно имя владельца и группа директории /dir/www/site.ru

Gifsicle используем для преобразования gif файлов.

#cd /usr/ports/graphics/gifsicle

Устанавливаем gifsicle-1.87

Запуск оптимизации всех .gif файлов сайта:

# find /dir/www/site.ru -name "*.gif" -print0 | xargs -0 gifsicle -b -O2

-b перезаписывать текущий файл преобразованным\

Перед любым преобразованием оригинальных изображений, на всякий случай, делаем их резервные копии

tidy-html5 используется для очистки и подготовки печати HTML/XHTML/XML документов, устранения некоторых ошибок.

# cd /usr/ports/www/tidy-html5

Устанавливаем tidy-html5-4.9.18

Оптимизацию производим следующей строкой:

# /usr/bin/find /path/site.ru -name "*.html" -print0 | xargs -0 tidy5 -utf8 -w 0 -c -n -m

Команда:
# tidy5 /path/index.html -обработает но не изменит index.html, результат выводится в консоль.
# tidy5 -m /path/index.html -обработает и изменит index.html

-indent, -i -сохраняет/создаёт отступы в документе
-modify, -m -изменения вносятся в обрабатываемый исходный файл
-wrap <column>, -w -при возможности, ограничение длины строки <column> -количество символов. -w 0 функция отключена. По умолчанию <column>=68
-upper, -u -тэги в верхний регистр
-clean, -c -replace FONT, NOBR and CENTER tags by CSS
-numeric, -n -цифры написанные текстом заменяются на цифры
-utf8 -входной и выходной контент в utf8

После tidy и любой другой обработки файлов сервера, на всякий перезапускаем apache.

yuicompressor минификация .js и .css.

# cd /usr/ports/www/yuicompressor

Устанавливаем yuicompressor-2.4.8_1

Команда:

# find /path/site.ru/CSS -name "*.css" -print0 | xargs -0 /usr/local/bin/yuicompressor --charset utf-8 -v -o '.css$:-min.css'

Все .css файлы в папке /path/site.ru/CSS будут преобразованны в минифицированные css копии с постфиксом "-min" после имени файла.
Команда:

# find /path/site.ru/CSS -name "*.css" -print0 | xargs -0 /usr/local/bin/yuicompressor --charset utf-8 -v -o '.css$:.css'

Не создаются копии, а меняются оригиналы

Для .js команда:

# find /path/site.ru/JSC -name "*.js" -print0 | xargs -0 \
/usr/local/bin/yuicompressor --charset utf-8 --nomunge -v -o '.js$:.js'

Выполняется только минификация. Обфускация не производится. Для обфускации нужно настроить ключи соответствующим образом

Для оптимизации всего сайта можно воспользоваться скриптом:

#!/bin/sh - 
find /path/site.ru -name "*.html" -print0 | xargs -0 \
tidy5 -utf8 -w 0 -n -b -omit -m
#CSS minificator by yuicompressor
find /path/site.ru/CSS -name "*.css" -print0 | xargs -0 \
/usr/local/bin/yuicompressor --charset utf-8 -v -o '.css$:.css'
#JS minificator by yuicompressor. Obfuscation off
find /path/site.ru/JSC -name "*.js" -print0 | xargs -0 \
/usr/local/bin/yuicompressor --charset utf-8 --nomunge -v -o '.js$:.js'
#Picture optimize .gif by gifsicle, .jpg by jpegoptim, .png optipng
#chown usd because optipng change user
/usr/sbin/chown -R user:group /path/site.ru
/usr/bin/find /path/site.ru -name "*.gif" -print0 | xargs -0 \
gifsicle -b -O2
/usr/bin/find /path/site.ru -name "*.jpg" -print0 | xargs -0 \
jpegoptim --all-progressive --strip-all -ft
/usr/bin/find /path/site.ru -name "*.png" -print0 | xargs -0 \
optipng -o5 -strip all -force
/usr/sbin/chown -R user:group /path/site.ru
#Apache restart
apachectl restart

Можно масштабировать решение на любое количество сайтов сервера.
В любом случае, для каждого сайта скрипт будет несколько отличаться настройками. Например могут быть случаи, когда .css, .js, и п.р. файлы являются контентом сайта и обрабатываться не должны. Т.е. нужно обрабатывать только те директории, в которых хранятся файлы относящиеся к функционированию сайта.
Проблема текущего решения в скорости выполнения т.к. для каждого типа файла каждый раз заново проводится рекурсивный просмотр всех папок. Оптимальным решением будет однократный перебор всех файлов сайта.

Нижеприведённый bash скрипт реализует вышеописанный алгоритм. Через find один раз читаются все файлы указанной директории. Далее анализируется каждый файл на принадлежность к jpg gif png html css js и производится соответствующая обработка. Js css файлы обрабатываются только в указанных папках. Также можно запретить обработку конкретных файлов в папке. jph gif png html файлы по умолчанию разрешены к обработке, но можно задать отдельные файлы и папки, в которых обработка производиться не будет. Например запретить обработку html файла google идентификации.

Скрипт site_optimization


#!/usr/local/bin/bash
#Site path
DIR="/path/site.ru"

#Default all enable
#Optimization disable for files array:
html_block_file_list=(wmail_a23456fabc11223.html google12fafa3f3f3f4567.html)
css_block_file_list=()
js_block_file_list=()
jpg_block_file_list=()
gif_block_file_list=()
png_block_file_list=()
#Optimization disable for dir array:
html_block_dir_list=()
jpg_block_dir_list=()
gif_block_dir_list=()
png_block_dir_list=()
#CSS and JS optimization enabled only in this folder array:
css_allow_dir_list=(/path/site.ru/CSS)
js_allow_dir_list=(/path/site.ru/JSC)

DIRF=$( find ${DIR} -type f -name '*.gif' \
                         -o -name '*.jpg' \
                         -o -name '*.png' \
                         -o -name '*.css' \
                         -o -name '*.js' \
                         -o -name '*.html' )

    for file in $DIRF
    do
        exten=${file##*.}
        filename="${file##*/}" #file name
        dirname="${file%/*}" #dir name
        case "$exten" in
            "jpg")
                if (( ${#jpg_block_dir_list[@]}>0 )); then      #DIR block list check
                    for a in "${jpg_block_dir_list[@]}"; do
                        if [ "$a" == "$dirname" ]; then continue 2 #go to next              
                fi done fi
                if (( ${#jpg_block_file_list[@]}>0 )); then     #File block list check
                    for a in "${jpg_block_file_list[@]}"; do
                        if [ "$a" == "$filename" ]; then continue 2 #go to next
                fi done fi
                jpegoptim --all-progressive --strip-all -ft $file
                echo "$file -OK"
            ;;
            "gif")
                if (( ${#gif_block_dir_list[@]}>0 )); then      #DIR block list check
                    for a in "${gif_block_dir_list[@]}"; do
                        if [ "$a" == "$dirname" ]; then continue 2 #go to next
                fi done fi
                if (( ${#gif_block_file_list[@]}>0 )); then     #File block list check
                    for a in "${gif_block_file_list[@]}"; do
                        if [ "$a" == "$filename" ]; then continue 2 #go to next
                fi done fi
                gifsicle -b -O2 $file
                echo "$file -OK"
            ;;
            "png")
                if (( ${#png_block_dir_list[@]}>0 )); then      #DIR block list check
                    for a in "${png_block_dir_list[@]}"; do
                        if [ "$a" == "$dirname" ]; then continue 2 #go to next
                fi done fi
                if (( ${#png_block_file_list[@]}>0 )); then     #File block list check
                    for a in "${png_block_file_list[@]}"; do
                        if [ "$a" == "$filename" ]; then continue 2 #go to next
                fi done fi
                FUSER=$( ls -ld $file | awk 'NR==1 {print $3}' )
                FGROUP=$( ls -ld $file | awk 'NR==1 {print $4}' )
                optipng -o5 -strip all -force $file
                chown $FUSER:$FGROUP $file #chown usd because optipng change user
                echo "$file -OK"
            ;;
            "html")
                if (( ${#html_block_dir_list[@]}>0 )); then      #DIR block list check
                    for a in "${html_block_dir_list[@]}"; do
                        if [ "$a" == "$dirname" ]; then continue 2 #go to next
                fi done fi
                if (( ${#html_block_file_list[@]}>0 )); then     #File block list check
                    for a in "${html_block_file_list[@]}"; do
                        if [ "$a" == "$filename" ]; then continue 2 #go to next
                fi done fi
                tidy5 -utf8 -w 0 -n -b -q -omit -m $file
                echo "$file -OK"
            ;;
            "css")
                if (( ${#css_block_file_list[@]}>0 )); then     #File block list check
                    for a in "${css_block_file_list[@]}"; do
                        if [ "$a" == "$filename" ]; then continue 2 #go to next
                fi done fi
                if (( ${#css_allow_dir_list[@]}>0 )); then      #DIR block list check
                    for a in "${css_allow_dir_list[@]}"; do
                        if [ "$a" == "$dirname" ]; then 
                yuicompressor --charset utf-8 -v -o '.css$:.css' $file
                echo "$file -OK"
                        continue 2      
                fi done fi
            ;;                                                                      
            "js")
                if (( ${#js_block_file_list[@]}>0 )); then     #File block list check
                    for a in "${js_block_file_list[@]}"; do
                        if [ "$a" == "$filename" ]; then continue 2 #go to next
                fi done fi
                if (( ${#js_allow_dir_list[@]}>0 )); then      #DIR block list check
                    for a in "${js_allow_dir_list[@]}"; do
                        if [ "$a" == "$dirname" ]; then
                yuicompressor --charset utf-8 --nomunge -v -o '.js$:.js' $file
                echo "$file -OK"
                        continue 2
                fi done fi
            ;;
            *)
                #do nothind
            ;;
        esac
    done

#Apache restart
apachectl restart

exit 0

На практике скрипт справляется отлично, но отслеживать ошибки и предупреждения очень неудобно. Например ошибки html выявленные tidy5. Сообщение после обработки .html файла без ошибок выглядит так:


...
Info: Document content looks like HTML5
No warnings or errors were found.
...

Сообщения при наличии ошибок выявленных tidy5:

line 57 column 81 - Error: <filename> is not recognized!
line 57 column 81 - Warning: discarding unexpected <filename>
line 58 column 91 - Error: <filename> is not recognized!
line 58 column 91 - Warning: discarding unexpected <filename>
line 71 column 81 - Error: <filename> is not recognized!
line 71 column 81 - Warning: discarding unexpected <filename>
line 72 column 91 - Error: <filename> is not recognized!
line 72 column 91 - Warning: discarding unexpected <filename>
line 132 column 81 - Error: <filename> is not recognized!
line 132 column 81 - Warning: discarding unexpected <filename>
line 133 column 91 - Error: <filename> is not recognized!
74 warnings, 72 errors were found! Not all warnings/errors were shown.

This document has errors that must be fixed before
using HTML Tidy to generate a tidied up version.

В общем нужно добавит парсер добавляющий ошибки в файл


Copyright ©Новиков Алексей Александрович,

2023 Санкт-Петербург, 197372, ООО "Антех ПСБ",

anteh собака bk.ru