Недавно я наткнулся на одну очень интересную тему для WordPress — WP-Coda. Выглядит просто шикарно! Но дело не в этом.
Эта тема использует довольно много эффектов, реализованных с помощью JavaScript.
Мне стало интересно, во сколько эта красота обходится посетителям, и оказалось, что не так уж и дорого. Всего один js-файл размером 45кБ.
Дело в том, что автор упаковал семь исходных файлов в один и после этого сжал его упаковщиком вроде Packer JavaScript en PHP.
Но первый же эксперимент показал, что это не предел. Если упаковать этот файл в gzip архив, то его размер уменьшается до 21кБ. А большинство современных браузеров прекрасно работают с такими архивами.
При этом нет необходимости что-либо переделывать в самой теме.
Достаточно создать архив и положить его в одну папку с исходным файлом.
После этого в файл .htaccess добавляем правила:
<IfModule mod_rewrite.c> RewriteEngine On AddEncoding gzip .gz RewriteCond %{HTTP:Accept-encoding} gzip RewriteCond %{HTTP_USER_AGENT} !Safari RewriteCond %{REQUEST_FILENAME}.gz -f RewriteRule ^(.*)$ $1.gz [QSA,L] </IfModule>
Работают эти правила так.
1) включаем RewriteEngine;
2) указываем, что файлы с расширением .gz имеют MIME тип gzip;
3) начинаем проверки:
3.1) если браузер принимает gzip;
3.2) если это не Safari (у него вроде есть проблемы с gzip);
3.3) если существует файл с таким же именем, как и у запрошенного, но с расширением .gz;
4) если все проверки прошли успешно, то добавляем к имени файла расширение .gz и отправляем этот файл браузеру.
Таким образом, если браузер не работает с gzip, то он получит исходный файл, если поддерживает – получит архив.
Посетитель разницы не заметит. Разве что немного увеличится время загрузки страницы.
В качестве примера, взгляните на скриншоты Firebug, сделанные для блога с темой WP-Coda.
Исходный вариант:
После сжатия и установки правил в .htaccess:
Кстати, заметьте, имя файла в обоих случаях одно и тоже. Изменяется только его размер. Т.е. браузер в обоих случаях считает, что получил файл, указанный в теге script
(global.js
), а сервер отправляет в первом случае global.js
, а во втором — global.js.gz
.
На мой взгляд, такой подход имеет только один недостаток. Во время разработки очень не удобно работать с одним большим js файлом, тем более сжатым 😉
Вручную упаковывать файлы тоже не интересно, поэтому нужно автоматизировать процесс.
Для этих целей я написал небольшой php скрипт.
//подключаем библиотеки require_once 'libs/jsmin-1.1.1.php'; /** * Путь к папке со скриптами (отностильно этого скрипта) */ define('JS_DIR', "test_site/js/"); /** * Имя упакованного файла (будет размещен в папке со скриптами) */ define('JS_OUTPUT_FILE', 'global.js'); //определяем папку в которой находится скрипт $scriptDir = substr($_SERVER['SCRIPT_FILENAME'], 0, strrpos($_SERVER['SCRIPT_FILENAME'], '/') + 1); $resStr = ""; //открываем папку и получаем список файлов с расширением "js" if ($dh = opendir($scriptDir.JS_DIR)) { while (false !== ($file = readdir($dh))) { if ((substr($file, strrpos($file, '.') + 1) == "js") && ($file != JS_OUTPUT_FILE)) { $resStr .= "/*---------".$file."---------*/\n"; //сжимаем текущий файл $resStr .= JSMin::minify(file_get_contents($scriptDir.JS_DIR.$file))."\n\n"; } } closedir($dh); //сохраняем сжатые данные в файл if ($fh = fopen($scriptDir.JS_DIR.JS_OUTPUT_FILE, 'w')) { fwrite($fh, $resStr); fclose($fh); } else { echo "Ошибка: не могу открыть файл для записи: ".$scriptDir.JS_DIR.JS_OUTPUT_FILE; } echo "Скрипты упакованы файл: ".JS_DIR.JS_OUTPUT_FILE."<br />"; //архивируем данные (используем самую высокую степень сжатия) $gzData = gzencode($resStr, 9); //создаем архив if ($fzip = fopen($scriptDir.JS_DIR.JS_OUTPUT_FILE.".gz", 'wb')) { fwrite($fzip, $gzData); fclose($fzip); } else { echo "Ошибка: не могу открыть файл для записи: ".$scriptDir.JS_DIR.JS_OUTPUT_FILE.".gz"; } echo "Создан архив: ".JS_DIR.JS_OUTPUT_FILE.".gz"; } else { echo "Ошибка: не могу открыть папку со скриптами"; }
Принцип работы следующий. Вы указываете папку с js файлами (JS_DIR
) и имя файла в который будут упакованы все скрипты (JS_OUTPUT_FILE
).
Скрипт читает содержимое всех файлов с расширением js из папки и сжимает его.
Примечание. Для сжатия используется PHP версия библиотеки JSMin. Она просто удаляет пробелы и комментарии из исходных файлов.
После этого сжатые скрипты записываются в файл, указанный в JS_OUTPUT_FILE
. Именно этот файл нужно подключать к вашим страницам.
Следующим этапом php скрипт создает архив (с помощью функции gzencode
), который получает имя JS_OUTPUT_FILE.gz
.
Для тестирования я взял библиотеку jQuery и написал js-файл с небольшой функцией, которая создавала пару эффектов.
Т.е. в исходном варианте было 2 файла:
jquery-1.2.3.js
– 96кБ
script.js
– 1кБ
Сжатый вариант:
global.js
– 53,1кБ
Архивный вариант:
global.js.gz
– 16кБ
Как видите, разница довольно ощутимая.
Если есть желание поэкспериментировать, качайте архив с скриптом и библиотекой JSMin.
До встречи!