Разгоняем сайт сжатием css и js

Опубликовано 21.04.2010 в 11:09 в разделе ,
На правах рекламы: Ремонт дизеля тигуан: цены на ремонт АвтоДиагност.

Тема ускорения загрузки сайтов на WordPress и других подобных системах известна давно и далеко не нова. Существует множество способов просто разогнать свой сайт, сжав при этом редко меняющиеся, но достаточно тяжеловесные файлы — js-скрипты и css-стили. Есть один простой, но очень эффективный способ ускорить загрузку сайта и значительно уменьшить время загрузки его страниц.

Первое, что приходит в голову — включить автоматическое сжатие трафика на веб-сервере. Идея интересная, скорость загрузки страниц сайта значительно увеличивается, а объём загружаемых страниц уменьшается, но при достаточно высокой нагрузке сервер будет тратить слишком много времени на сжатие неизменного контента — мы получаем перегрузку.

Второй, и более приемлемый вариант ускорения загрузки сайта — хранить на сервере уже сжатые файлы скриптов и стилей. Им я и предлагаю воспользоваться.

Сжатие файлов

Если на сайте есть всего два-три файла стилей и скриптов, то сжать их можно вручную. В случае с WordPress так, увы, поступить нельзя, потому что js и css там — «туева хуча».

Для сжатия файлов напишем очень простенький скрипт на php. Я запускаю его из-под root-а у себя на сервере, но вполне можно запускать его и у себя на домашней машине (под Windows), на Windows-сервере, без проблем с правами доступа, или на сервере с suPHP.

<?php

function compress($dir) {
	$d = opendir ($dir);
	while ($f = readdir ($d)) {
		if ($f == '.' || $f == '..') continue;
		if (is_dir ($dir . '/' . $f)) {
			compress ($dir . '/' . $f);
		} elseif (preg_match('#\.(css|js)$#si', $f)) {
			$ft1 = filemtime ($dir . '/' . $f);
			$ft2 = ( file_exists ($dir . '/' . $f . '.gz') ) ? filemtime ($dir . '/' . $f . '.gz') : 0;
			if ($ft1 > $ft2) {
				$dt = file_get_contents ($dir . '/' . $f);
				$g = gzopen ($dir . '/' . $f . '.gz', 'wb9');
				gzwrite ($g, $dt);
				gzclose ($g);
			}
		}
	}
	closedir ($d);
}

compress (dirname (__FILE__));

?>

Этот простенький файлик мгновенно сожмёт все требуемые файлы, где бы они ни были.

Настройка .htaccess

Второй шаг в работе сжатия — это настройка файла .htaccess на распознавание подходящих браузеров и выдачу им сжатого контента.

Научим .htaccess перенаправлять браузер на сжатый файл, если такое возможно.

AddEncoding gzip .gz
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{HTTP_USER_AGENT} !Safari
RewriteCond %{REQUEST_FILENAME} \.css$ [OR]
RewriteCond %{REQUEST_FILENAME} \.js$
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)\.(css|js)?$ $1.$2.gz [QSA,L]

Чтобы файлы не воспринимались «криво», добавим блок, который отправил клиенту верные заголовки. Проверьте, mod_headers должен быть включен в Apache, в противном случае ничего не будет работать.

<IfModule mod_headers.c>
	Header append Vary User-Agent
	<FilesMatch .*\.js.gz$>
	ForceType text/javascript
	Header set Content-Encoding: gzip
	Header set Cache-control: private
	</FilesMatch>
	<FilesMatch .*\.css.gz$>
	ForceType text/css
	Header set Content-Encoding: gzip
	Header set Cache-control: private
	</FilesMatch>
</IfModule>

После этого можем сохранять файл .htaccess и наслаждаться результатом.

Файлы

Для самых ленивых, я выкладываю архив с готовыми файлами gzipper.php и .htaccess для WordPress.

При небольшой переработке, они подойдут для любой CMS.

Тестирование

Для проверки, откроем FireFox с установленным расширением TamperData и проверим, какого именно типа файлы скачивает наш браузер при обращении к странице.

В данный момент такой способ «раздачи слонов» действует на моём сайте http://www.fld.mrsu.ru и весьма успешно, надо сказать, работает там вместе с WordPress MU и BuddyPress. Не хуже система работает на http://www.av13.ru — как видите, сайт грузится достаточно быстро! ;)