Автоматическая оптимизация изображений сервера, 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.
|
В общем нужно добавит парсер добавляющий ошибки в файл