Если правильно выставить заголовки касательно кеширования (а точнее не выставлять параметры No-Cache), то браузер, запрашивая файл, выставит заголовок If-Modified-Since. Если файл не изменился с времени, указанного в этом заголовке, то ничего передаваться не будет, а вернётся ответ HTTP 304 Not modified.

Это поведение не решает проблему задержки при открытии страницы. На каждый запрос требуется порядка 30 мс. Если на странице 30 картинок, то это уже почти секунда на то, что бы просто проверить, не поменялось ли чего-нибудь. Для того, что бы браузер успокоился и не переспрашивал на каждый файлик, не поменялся ли он, можно выставить заголовок Expires (парамер expires у nginx-а). Если этот заголовок выставить, браузер уже до конца периода Expires не будет переспрашивать и время открывания страницы сильно сократится.

Возникает сразу две проблемы:


  1. как, собственно, указать, что файл всё таки изменился, несмотря на все наши предположения о его неизменности?

  2. этот механизм не работает с рельсовым подписыванием времени модификации.

Когда запрашивается урл, у которого не пустой QUERY_STRING, браузер всё равно переспросит If-Modified-Since при запросе файла.

Я решил эту проблему таким образом: перед расширением подписываю номер SVN ревизии: /stylesheets/style.v423.css. В случае, когда файл не в SVN, подписываю время модификации: /stylesheets/all.v1234254534.css.
Все такие файлы отдаются с заголовком expires 10y. Т.е. никогда не поменяются. Плюс к этому в конфиге nginx-а настроена перепись, что бы выбрасывать все такие вставки.

Для этих целей я написал себе плагин: http://svn.maxidoors.ru/rails_plugins/svn_asset_path.
Для его активации требуется сделать всё, как в инструкции в файле README. Если в script положить yuicompressor.jar, то плагин ещё и сожмёт все файлы прежде чем слить их вместе, в случае ключа :cache => true.

Номер ревизии в SVN читаю напрямую из файликов .svn/entries. Не очень эстетично, зато быстро и удобно.

Sidebar