Библиотека HTTP_StaticMerger 2.x позволяет "на лету" сливать набор
статических файлов (CSS и JS) и, таким образом, ускорять загрузку страницы,
экономя HTTP-запросы. Ближайший аналог minify, имеющий более расширенный
функционал, но зато большую сложность и размер.
Естественно, библиотеку рекомендуется применять совместно с кэширующим
reverse proxy (например, nginx) для минимизации времени ответа. Возможности:
Обработка директив @import и удаление комментариев из кода, что экономит трафик.
"Слитый" URL зависит от времени модификации входящих в него файлов.
Поддержка заголовков HTTP If-Modified-Since, If-None-Match, Etag.
Работа под очень высокой нагрузкой (при использовании reverse-proxy сервера с модулем кэширования, например, nginx).
В версии 2.x поддерживается цифровое подписывание URL, защищающее от "зафлуживания" файловой системы злоумышленником в случае использования nginx.
Владельцы нагруженных проектов! Прочтите, пожалуйста, раздел Nginx: gzip-сжатие и кэширование
в нижней части страницы, чтобы узнать, как правильно использовать HTTP_StaticMerger под нагрузкой.
Суть проблемы
В сложных сайтах количество подключаемых CSS- и JS-файлов может быть достаточно большим,
из-за чего скорость загрузки страницы сильно страдает:
Загрузка каждого файла порождает отдельный HTTP-запрос, и браузер не может показать
содержимое страницы до тех пор, пока не загрузятся все до единого CSS- и JS-файлы. Естественно, это
замедляет отображение.
Библиотека HTTP_StaticMerger позволяет использовать единый URL для загрузки сразу
нескольких CSS- или JS-файлов:
В целях отладки иногда бывает удобно временно отключить слияние файлов. Для этого передайте третий
параметр в метод getHtml(), равный true. Тогда каждый файл будет представлен отдельным
тэгом <script> или <link>:
Если вы планируете внедрять HTTP_StaticMerger в сильно нагруженном проекте,
пожалуйста, не пытайтесь сделать это "в лоб". Дело в том, что процедура слияния файлов
происходит при каждом HTTP-запросе и занимает ощутимое время (средняя машина выдает
примерно 100-200 запросов слияния в секунду).
Чтобы разгрузить сервер, используйте кэширующий reverse proxy перед веб-сервером
(например, nginx). Пусть он кэширует "навечно" все запросы к merge-скрипту:
Листинг 6: /merge.php обработчик для слияния с gzip-сжатием
<?php
require_once "../lib/HTTP/StaticMerger.php";
ob_start();
$merger = new HTTP_StaticMerger('a-secret-and-constant-string');
$merger->main('windows-1251');
$c = ob_get_clean();
if ($c && empty($_SERVER['HTTP_NOGZIP'])) ob_start(array('ob_gzhandler', 9));
echo $c;
Обратите внимание: мы включаем gzip-сжатие только в случае, если nginx это не запретил (переменная HTTP_NOGZIP
устанавливается в конфигурации nginx в зависимости от браузера, см. ниже). Также запрещаем gzip-сжатие для
ответов с "пустым" телом (например, "304 Not Modified"), иначе возникают проблемы как минимум в Google Chrome.
# Включаем кэширование для сжатых файлов.
proxy_cache_path /var/cache/nginx levels= keys_zone=merge:10m;
location /merge.php {
set $no_gzip 0;
if ($http_user_agent ~ "MSIE [4-6]\.|Safari|Konqueror") {
# В этих браузерах имеются баги при обработке gzip-сжатых файлов с ДЛИННЫМИ URL-ами.
set $no_gzip 1;
}
if ($http_accept_encoding !~ "gzip") {
set $no_gzip 1;
}
proxy_pass http://127.0.0.1:80;
proxy_set_header Host $host;
# Nginx caching.
proxy_cache merge;
proxy_cache_valid 200 304 404 240h;
proxy_cache_key "$no_gzip|$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
proxy_set_header NOGZIP $no_gzip;
}
Внимание! В MS Internet Explorer 6.0 и младше отмечаются проблемы с кэшированием gzip-сжатых данных, если длина URI CSS- или JS-файла превышает 215 символов. Соответственно, мы выключаем в этих браузерах сжатие.
Или - конфигурация для FastCGI PHP
А эти настройки для поклонников FastCGI-версии PHP:
Листинг 11: улучшение вида URL слияния при помощи mod_rewrite
RewriteRule ^m/(.*) merge.php?$1
Старайтесь, однако, избегать части "?..." в URL слияния, т.к. некоторые старые
браузеры отключают клиентское кэширование для таких адресов либо работают неоптимально.