Кэл Хендерсон из 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 частей:
- Грабли, которые будут генерировать объединенные файлы
- Помощник представления для вывода различных 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, половина удовольствия — это самое элегантное решение. Тот факт, что его обычно так просто реализовать, является дополнительным бонусом.