Компресирани ресурсите в уеб страница, когато mod_deflate не е наличен или не е за предпочитане

Компресиране на ресурси като javascript и css файлове преди да се изпратят на клиента е абсолючно задължително за всеки модерен сайт. Този похват помага за намаляване на проблемите от растящите размери на скриптовете в Web 2.0 сайтовете. Компресията води до по-бързо зареждане на страниците, по-малко трафик и разходи за хостинг.


mod_deflate


Apache httpd съвъра предлага много удобен модул за тази цел - mod_deflate. Той осигурява прозрачна компресия на съдържанието преди да се изпрати до клиента. Настрйката е тривиална - няколко реда в htaccess файла:

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE application/javascript text/css
</IfModule>


Проблемът тук е следния: mod_deflate компресира ресурса при всяко достъпване. Това води до значително увеличние на използването на процесора и поради този факт модулът не е наличен на повечето платформи за споделен хостинг.


Решението
 


Липсата на mod_deflate не означава автоматично невъзможност за компресия на съдържанието. Ето една идея: нека всеки статичен файл има своя компресирана версия, която се предоставя вместо оригинала ако браузъра поддържа компресия. Нека всеки javascript файл scipt.js има компресирана версия script.jsgz и всеки CSS style.css - style.cssgz. Долните rewrite правила реализират точно горната идея. Уловката тук е да се настрои правилно content-type на новосъздадените файлове .jsgz и .cssgz, защото иначе повечето браузъри отказват да ги обработват.

RewriteEngine on

RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}gz -f
RewriteRule (.*)\.css$ $1\.cssgz [L]

AddType "text/css;charset=UTF-8" .cssgz
AddEncoding gzip .cssgz

RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}gz -f
RewriteRule (.*)\.js$ $1\.jsgz [L]

AddType "text/javascript;charset=UTF-8" .jsgz
AddEncoding gzip .jsgz



Автоматично генериране на компресирани версии
 


За да не се претърсва на ръка целия сайт за променени ресурси може да се използва долния скрипт. Просто го добавете в своя crontab, за да се пуска на всеки няколко часа:

bash update-compressed-content.sh ~/public_html '*.css'
bash update-compressed-content.sh ~/public_html '*.js'

update-compressed-content.sh:


#!/bin/bash

dir=$1
pattern=$2
test_run=$3

exec_line() {
    cmd="$1"
    do_not_run="$2"
   
    echo "Executing $cmd";
    if [ "X" == "X$do_not_run" ]
    then
        out= eval $1
        echo "Result is $out"
    fi
}

if [ -z "$dir" ] || [ -z "$pattern" ]
then
    echo "Usage: $0 <directory> <pattern>"
    exit 1
fi

echo "find \"$dir\" -name \"$pattern\""
find "$dir" -name "$pattern" | while read fileto
do
    echo $fileto
    if [ -e "${fileto}gz" ] && [ "${fileto}gz" -nt "$fileto" ]
    then
        echo "Compressed content for $fileto is up to date"
    else
        echo "Compressing $fileto"
        exec_line "cat '$fileto' | gzip > '${fileto}gz'" $test_run
    fi

done

Няма коментари

Обратно към списъка със статиите

Тази страница последно е променяна на 2024-04-22 02:59:01