Статьи

Сокращение HTTP-запросов: идея для плагина

Кэл Хендерсон из Flickr недавно опубликовал публикацию Serving Javascript Fast , в которой рассказывает о подходе, который они используют в Flickr, для уменьшения количества HTTP-запросов на страницу и эффективного распространения новых изменений в ресурсах.

В Rails 1.1 мы получаем распространение измененных ресурсов бесплатно: все URL-адреса статических ресурсов (javascripts, stylsheets, images) получают свою последнюю измененную временную метку, добавляемую к их URL-адресу. Когда ресурс обновляется, URL-адрес изменяется, и все клиенты загружают последнюю версию.

Например, следующий код:

<%= stylesheet_link_tag 'common' %>

сгенерирует что-то похожее на:

<link href="/stylesheets/common.css?1148952578" media="screen" rel="Stylesheet" type="text/css" />

Хотя и не такой эффективный, как подход Flickr, он прост и работает для большинства людей.

Другая проблема, с которой столкнулся Cal — сокращение количества HTTP-запросов, — это не то, что мы получаем бесплатно в Rails. Фактически, настройка по умолчанию для приложения Rails, которое использует script.aculo.us, имеет 4 файла javascript. Эти четыре файла не часто меняются (только при обновлении Rails), все они часто нужны вместе и часто обновляются одновременно. Звучит как хороший кандидат для сокращения HTTP-запросов? Было бы неплохо, если бы при развертывании нашего приложения на производственном сервере мы могли объединить их вместе, и наши взгляды указывают на объединенную версию, и все это происходит автоматически. Похоже, хороший кандидат на плагин … давайте назовем это … CombinedAssets!

CombinedAssets будет состоять из 2 частей:

  1. Грабли, которые будут генерировать объединенные файлы
  2. Помощник представления для вывода различных URL-адресов активов на производственном сервере

В вашем файле environment.rb вы бы объявили несколько наборов ресурсов:

 
CombinedAssets.javascripts[:rails] = %w(prototype controls dragdrop effects)
CombinedAssets.stylesheets[:yui] = %w(fonts reset grids)

Тогда, по вашему мнению, вы можете просто позвонить:

 
<%= javascript_include_tag combined_javascripts(:rails) %>
<%= stylesheet_link_tag combined_stylesheets(:yui) %>

Вывод которого будет выглядеть примерно так:

 
<script src="/javascripts/prototype.js?1147878861" type="text/javascript"></script>
<script src="/javascripts/controls.js?1147878861" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1147878861" type="text/javascript"></script>
<script src="/javascripts/effects.js?1147878861" type="text/javascript"></script>
<link href="/stylesheets/fonts.css?1147878863" media="all" rel="Stylesheet" type="text/css" />
<link href="/stylesheets/reset.css?1147878863" media="all" rel="Stylesheet" type="text/css" />
<link href="/stylesheets/grids.css?1147878863" media="all" rel="Stylesheet" type="text/css" />

и следующее в производстве:

 
<script src="/javascripts/prototype_controls_dragdrop_effects.js?1147878861" type="text/javascript"></script>
<link href="/stylesheets/fonts_reset_grids.css?1147878863" media="all" rel="Stylesheet" type="text/css" />

Это на 5 меньше HTTP-запросов для новых посетителей.

Конечно, нам также понадобится задача rake, которая на самом деле объединяет файлы, и в сочетании с Capistrano это может произойти автоматически на производственных серверах во время развертывания.

С таким лаконичным языком, как Ruby, и фреймворком, таким как Rails, половина удовольствия — это самое элегантное решение. Тот факт, что его обычно так просто реализовать, является дополнительным бонусом.