пользователи видят страницу без изображений.

Однако у этого подхода есть и недостатки. Совмещая все наши ресурсы, мы заставляем пользователя загружать всё и сразу. Разделив содержимое между разными файлами, мы могли бы распределить тяжесть загрузки поверх нескольких страниц (или вообще избежать загрузки отдельных блоков – зависит от поведения пользователя). Если же мы замедлим загрузку первой страницы, чтобы ускорить загрузку всех остальных, то можем столкнуться с тем, что второй страницы многие пользователи просто не дождутся.

Исторически этот крупный недостаток такого подхода нечасто брался в расчет. Но для системы, в которой постоянные изменения содержимого статических файлов – обычное дело, это важно, поскольку любое изменение в большом едином блоке требует, чтобы клиент перегрузил себе полный рабочий набор CSS или JavaScript. Если приложение представляет собой монолитный исходник на JavaScript размером 100 Кбайт, значит, каждая мелочь приводит к принудительной загрузке лишних 100 Кбайт.

Один в поле не воин

В качестве альтернативного подхода постараемся придерживаться золотой середины. Разобъем наши CSS– и JavaScript-ресурсы на множество подфайлов, сохраняя в то же время количество этих файлов функционально невысоким. С одной стороны, нам удобно разрабатывать приложения, разбивая код на логические блоки. С другой стороны, для работы приложения важно, чтобы этих блоков было не слишком много (так что нам приходится объединять эти файлы). Компромисса можно добиться, сделав определенные добавления к системе сборки билдов (набор инструментов, превращающий «грязный» код разработки в рабочий, готовый для развертывания код).

Для прикладного окружения, в котором среда разработки и среда исполнения четко разделены, подойдут простые техники управления кодом. Пусть в среде разработки код для пущей ясности разбит на множество логических блоков. Создадим в Smarty (язык шаблонов для PHP) простую функцию загрузки JavaScript:

{insert_js files='foo.js,bar.js,baz.js'}

function smarty_insert_js($args){

foreach (explode(‘,’, $args[‘files’]) as $file){

echo «<script type=»text/javascript' src='/javascript/$file'></script>n';

<script type='text/javascript' src='/javascript/foo.js'></script>

<script type='text/javascript' src='/javascript/bar.js'></script>

<script type='text/javascript' src='/javascript/baz.js'></script>

Пока все просто. Но затем мы во время сборки билда объединяем нужные файлы. Представьте, что в нашем примере мы должны объединить foo.js и bar.js в foobar.js, раз уж они почти всегда подгружаются вместе. Учтем этот факт при настройке нашего приложения и модифицируем код с учетом этой информации:

{insert_js files='foo.js,bar.js,baz.js'}

# map of where we can find .js source files after the build process

# has merged as necessary

$GLOBALS[‘config’][‘js_source_map’] = array(

‘foo.js’ => ‘foobar.js’,

‘bar.js’ => ‘foobar.js’,

‘baz.js’ => ‘baz.js’,

function smarty_insert_js($args){

if ($GLOBALS[‘config’][‘is_dev_site’]){

$files = explode(‘,’, $args[‘files’]);

$files = array();

foreach (explode(‘,’, $args[‘files’]) as $file){

$files[$GLOBALS[‘config’][‘js_source_map’][$file]]++;

$files = array_keys($files);

foreach ($files as $file){

echo «<script type=»text/javascript' src='/javascript/$file'></script>n';

<script type='text/javascript' src='/javascript/foobar.js'></script>

<script type='text/javascript' src='/javascript/baz.js'></script>

Исходный код шаблонов не меняется, что позволяет нам сохранять эти файлы разделенными во время разработки. Кроме того, мы можем написать собственный процесс объединения на PHP и использовать тот же самый конфигурационный блок при самом объединении (а использование одного и того же конфигурационного файла избавляет нас от необходимости синхронизации). А если брать по максимуму, то можно проанализировать использование скриптов и стилей на страницах сайта, чтобы определить, какие именно файлы лучше объединять (хорошие кандидаты для такого объединения – это файлы, которые почти всегда подгружаются вместе).

В случае с CSS можно начать с полезной модели, состоящей из двух стилей: основного стиля и стиля подраздела. Единый основной стиль используется во всем приложении, а разные стили подразделов контролируют разные функциональные области. В этом случае подавляющее большинство страниц подгружают только два стиля (один из которых кэшируется при первой загрузке – это, конечно, основной).

Для небольших наборов CSS и JavaScript такой подход может замедлить обработку первого запроса (в сравнении с «монолитным» подходом), но если сохранять количество компонентов на относительно низком уровне, то возможно и ускорение работы, поскольку в расчете на одну страницу приходится загружать меньше данных.

Сжатие

Когда речь заходит о сжатии, многие немедленно вспоминают mod_gzip. Однако с ним нужно соблюдать осторожность – mod_gzip, в общем-то, является злом или, по меньшей мере, причиной кошмарного расходования ресурсов. Основная идея сжатия проста. Браузеры, запрашивая ресурсы, указывают в заголовке, в каком виде они могут принять содержимое страницы. Это может выглядеть, например, так:

Accept-Encoding: gzip,deflate

Видя такой заголовок, сервер сжимает отсылаемое содержимое методами gzip или deflate с тем, чтобы клиент распаковал его на месте. Это загружает процессор как на клиенте, так и на сервере, однако уменьшает объем передаваемых данных. Это нормально. Однако вот как работает mod_gzip: он сжимает данные во временный файл на диске, а после отсылки данных удаляет этот файл. На больших системах вы очень быстро столкнетесь с ограничениями скорости ввода/вывода. Этого можно избежать, используя вместо mod_gzip mod_deflate (только в Apache 2), поскольку последний сжимает данные в оперативной памяти. Пользователи первой версии Apache могут создать RAM-диск и хранить временные файлы mod_gzip там – это не так быстро, как работа напрямую с оперативкой, но намного шустрее, чем писать все на жесткий диск.

Но даже без этого мы можем полностью избежать вышеописанных проблем, используя предварительное сжатие нужных статических ресурсов и последующую отправку их клиенту с помощью mod_gzip. Если добавить предварительное сжатие в сборку билда, то сам процесс пройдет для нас совершенно незаметно. Файлов, требующих упаковки, обычно не так уж много – мы не сжимаем изображения (поскольку это вряд ли приведет хоть к какой-то экономии – изображения и так уже достаточно сжаты), так что нам остается упаковать JavaScript, CSS и прочий статический контент. Но мы должны указать mod_gzip, где искать файлы для предварительной компрессии:

mod_gzip_can_negotiate Yes

mod_gzip_static_suffix .gz

AddEncoding gzip .gz

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату