Журнал «Компьютерра» № 20 от 30 мая 2006 года
Шрифт:
Так что залог видеоздоровья компьютера – установка по отдельности минимума необходимых декодеров. Тогда, возможно, и эта статья вам не пригодится.
Детали: Ускоряем JavaScript
Автор: Хендерсон, Кэл
Кажется, всего несколько дней назад мы рассказывали вам об истории Flickr, и вот – статья, написанная главным разработчиком этой компании Кэлом Хендерсоном. Статья довольно специфичная – это вполне конкретные советы по решению вполне конкретных проблем, с которыми может столкнуться практически любой веб-разработчик. Как правило, мы стараемся не публиковать материалы такого плана, однако и Веб 2.0 – штука довольно
Так называемые приложения Веб 2.0 предполагают более интенсивное использование CSS и JavaScript, чем раньше. Но для быстрой и качественной работы приложения мы должны оптимизировать размер и выдачу контента, который требуется для рендеринга страницы. На практике это означает, что мы должны сделать статический контент настолько маленьким и быстрым для загрузки, насколько это возможно, избегая немотивированной раздачи файлов, которые не претерпели изменений.
Эта задача несколько усложняется самой природой файлов CSS и JavaScript. В отличие от изображений, исходный код CSS и JavaScript скорее всего с течением времени будет меняться неоднократно. И нам нужно, чтобы после каждого изменения клиенты могли загрузить обновленные версии файлов, не пытаясь использовать старые версии, сохраненные в их локальном кэше (а также во всех кэшах, которые встретятся по пути). В этой статье мы обсудим, как облегчить жизнь пользователю – при первой и последующих загрузках страницы, а также по мере того, как приложение развивается и обновляется.
Кроме того, мы должны максимально упростить жизнь разработчиков, так что обсудим заодно и способы автоматизации процессов оптимизации. Немного предварительной возни позволит нам совместить легкость разработки с удобством использования – и все без изменения привычных практик.
Раньше считалось, что максимальной производительности можно добиться, объединив многочисленные CSS– и JavaScript-файлы в более крупные блоки. Вместо десятка JavaScript-файлов по 5 Кбайт каждый мы делали один файл размером 50 Кбайт. Хотя общий размер кода при этом не менялся, мы сокращали накладные расходы на обработку HTTP-запросов.
Также важен аспект распараллеливания. По умолчанию и IE и Mozilla/Firefox при использовании стабильного соединения загружают только два файла с одного домена (см. спецификацию HTTP 1.1, секция 8.1.4). Это означает, что пока не загрузятся все скрипты, мы не загружаем картинки. Все это время пользователи видят страницу без изображений.
Однако у этого подхода есть и недостатки. Совмещая все наши ресурсы, мы заставляем пользователя загружать всё и сразу. Разделив содержимое между разными файлами, мы могли бы распределить тяжесть загрузки поверх нескольких страниц (или вообще избежать загрузки отдельных блоков – зависит от поведения пользователя). Если же мы замедлим загрузку первой страницы, чтобы ускорить загрузку всех остальных, то можем столкнуться с тем, что второй страницы многие пользователи просто не дождутся.
Исторически этот крупный недостаток такого подхода нечасто брался в расчет. Но для системы, в которой постоянные изменения содержимого статических файлов – обычное дело,
В качестве альтернативного подхода постараемся придерживаться золотой середины. Разобъем наши 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 и использовать тот же самый конфигурационный блок при самом объединении (а использование одного и того же конфигурационного файла избавляет нас от необходимости синхронизации). А если брать по максимуму, то можно проанализировать использование скриптов и стилей на страницах сайта, чтобы определить, какие именно файлы лучше объединять (хорошие кандидаты для такого объединения – это файлы, которые почти всегда подгружаются вместе).