Клиентская оптимизация

индекс
163,90

ETag спешит на помощь

Ни для кого не секрет, что в протоколе HTTP, а точнее в той его части, что является ответом с сервера, есть такие замечательные заголовки, как Last-Modified и ETag (Подробнее можно прочитать в спецификации протокола). Призваны они ускорить процесс получения контента с сервера, а точнее избавить клиента от загрузки данных, которые не были изменены с момента предыдущего запроса.

Так вот. Для меня факт существования двух, по-сути одинаковых, механизмов сообщить клиенту изменилось ли содержимое страницы или нет немного настораживал. Немного. Точнее я его не понимал для чего нужен ETag, если мне всегда было достаточно одного Last-Modified и юзкейса для другого я даже и представить не мог (хотя меня этот вопрос, признаться честно, не особо и волновал).

Но это все было до вчерашнего дня, когда я попал в ситуацию, где Last-Modified не справился. И ситуация эта — достаточно распространенная — мультиязычный контент. В моем случае идентификатор текущего языка хранится в сессии на сервере и URL для разных языков один и тот же, что и привело, собственно, к проблеме. Начав работы по оптимизации сайта я включил условное кеширование и обнаружил, что переключатель языка перестал работать.

Вот тут-то мне и пригодился ETag вместо привычного Last-Modified. Причем строить я стал его очень незамысловато — а именно конкатенацией текущего языка и даты модификации контента. В этом случае при смене языка клиент получал для одного и того же URL различные ETag и соответственно перегружал страницу заново.

А в качестве заключения мне хотелось бы обратить внимание (и своё в превую очередь) на то, что не стоит сразу высмеивать и/или критиковать коллег по цеху, если некоторе вещи с первого взгляда кажутся нам нелепыми или глупыми. Возможно это мы сами пока что чего-то не замечаем.
+32
2 декабря 2009, 10:53
38

комментарии (43)

+1
tenshi #
etag — это, емнип, нововведение http1.1
а last-modified — соответственно http1.0, оставленное для обратной совместимости
+2
pashka_r #
Ну у меня бы первый вопрос напросился: а зачем, если уже есть один механизм? Собстенно он и возникал.
+1
tenshi #
затем, что он более продвинутый
0
sunnybear #
Перенесите, пожалуйста, в блог «Клиентская оптимизация»
+1
pashka_r #
так и сделал
+13
evilbloodydemon #
а вообще информация о языке должна быть частью url
+2
pashka_r #
Ну это тема для отдельного холивара. Я, например, не вижу в этом никакого смысла. Язык берется из сессии/куков, а если там ничего об этом не сказано, то тот, который просит клиент в заголовках запроса.
+5
sunnybear #
поисковики так хуже индексят — они же cookie не поддерживают
–1
pashka_r #
Есть подозрение, что они поддерживают http заголовки.
+2
sunnybear #
ну, значит, не все заголовки :)
–3
Artima #
А мне кажется, что это даже противоречит лицензии поисковиков.
+12
evilbloodydemon #
основной принцип хттп, между прочим, это то, что ресурс однозначно определяется урлом. но можно ему не следовать, конечно же, и етаги руками мастерить.
+1
moroz1999 #
Дайте, пожалуйста, пруфлинк.
0
tenshi #
http header vary
+13
Bonch #
Ага, а как тогда ссылку дать на страницу на конкретном языке?
–14
pashka_r #
Для чего вам давать ссылку на конкретном языке? Зачем за получателя решать на каком языке ему хотелось бы прочитать контент.

В любом случае, мне кажется это не самое подходящее место для обсуждения этого вопроса.
+18
MTonly #
Уникальной единице информации должен соответствовать уникальный URL. Конкретному URL — строго конкретная единица информации на конкретном языке. Разные языки (разные документы с физически разным содержимым) — разные URL. И дело не в поисковиках, а в простом здравом смысле.
+4
mjr27 #
Это все замечательно, пока речь идет об информации а не о формах, инструментах и т д.
К примеру, если в gmail будет отдельная ссылка на каждый язык интерфейса-- это уже выглядит победой теории над здравым смыслом.

Это не ради холивара; это просто к тому что не надо так категорично высказываться. У каждого правила есть своя область применимости
–1
MTonly #
У каждого правила есть своя область применимости
Несомненно, веб-интерфейсы — тема особая. Тем не менее, нет ничего страшного в раздельных URL-адресах для каждого языка в том числе и применительно к сервисам типа Gmail. Главное — не забыть дать пользователю наглядную возможность вручную выбрать нужный язык при необходимости.

Следует также учитывать, что, как и с обычными веб-страницами, совпадение перечней веб-страниц у разных языковых версий веб-интерфейса не является гарантированным. С раздельными URL’ами никогда (даже теоретически) не возникнет проблемы, когда англоговорящий человек даёт ссылку русскоговорящему, и тот попадает на страницу 404.
–1
Fduch #
Как хорошо, что люди всё-таки оставляют возможность переключить язык руками.
www.mydigitallife.info/2009/01/11/free-unlimited-activation-product-key-to-activate-windows-7-beta/ru/
0
Sane #
Как варианты: www.example.com/doc.html возвращает док на языке пользователя (из сессии), www.example.com/doc.html?ln=en возвращает английский док вне зависимости от сессии. И либо редиректы, если ты зашел без языка, либо на самой странице ссылки для языковых версий документа.
0
Goodkat #
Дописываешь hl=ru в GET-параметрах :)
+3
Dragonizer #
Представьте себе, ну, например, международный форум. У каждого пользователя в настройках указано, на каком языке будут надписи на кнопочках и т.п. (в то время как к непосредственному контенту это не имеет отношения). Какого, простите, черта, в ссылке должен содержаться язык?!
+1
MTonly #
Если контент (не логотип и не кнопки, а контент) вне зависимости от выбранного языка один и тот же, то и URL имеет смысл использовать один и тот же.
+1
kmike #
зависимость от языка реализуется с помощью Vary, нет?

С ETag'ами, кстати, проблемы разные есть еще. Например, с ними gzip не работает иногда. YSlow за ETag'и даже баллы снимает.
0
sunnybear #
нет, проблем нет, YSlow в данном месте глючит (хотя в правилах там как раз двусмысленно написано)
0
kmike #
может все-таки есть?
issues.apache.org/bugzilla/show_bug.cgi?id=39727
0
sunnybear #
это как вы ETag захотите выставлять. Его и ведь динамически (через тот же PHP) можно определять, а Last-Modified вообще не предполагает какой-то gzip-зависимой метки.
nginx последних версий, кстати, лишен этого бага
0
kmike #
Про Last-Modified речи и не шло. Ну и как-бы это не вариант всю статику через php прогонять. Да, и довольно логично, что ngnix последних версий лишен бага из багтрекера апача :)
0
sunnybear #
:) я к тому, что сейчас, в принципе, нет никаких предпосылок НЕ использовать ETag, а на кластерах он чуточку лучше (ведь Google, например, в SVN его и использует)
0
kmike #
я прекрасно понял, что Вы предлагаете статику отдавать ngnix'ом, а E-tag'и определять динамически в скриптах, но это ведь не отменяет того факта, что YSlow может вполне правильно указывать на наиболее распространенную нерабочую комбинацию ETag+Apache+mod_deflate.
0
sunnybear #
Все было бы хорошо, если бы Вы упоминали, в каких случаях эта комбинация не работает: когда мы запросили одним и тем же клиентом (например, прокси-сервером) сначала несжатую версию контента, затем сжатую — получили бы 304-ответ (при использовании If-None-Match) и отдали бы сжатую вместо несжатой. Только для статики существует Vary: User-Agent, Content-Encoding, которые данную проблему позволяют решить (в случае нормальных прокси-серверов, конечно :)

Т.е. проблема, конечно, есть, но при наличии прямых рук она на указанном окружении обходится (либо ее решение лежит уже за пределами данного окружения).
+1
chikuyonok #
Насколько я помню, есть еще очень серьезная проблема с использованием ETag на больших проектах, где статика дублируется на нескольких серверах. Из-за того, что в стандартной конфигурации апача для генерации ETag хэша используется inode файла. То есть в зависимости от того, куда направит балансировщик, получим абсолютно идентичные файлы, но разные тэги. Как результат — запрос пойдет мимо кэша.

Поэтому многие рекомендуют отключать ETag на крупных проектах.
+1
sunnybear #
да, но Google именно ETag использует. На больших проектах, где много статики, обычно не Apache используют. А ETag более конфигурируемый в этом плане, чем Last-Modified
0
bolk #
зачем же его выключать? Достаточно задать:

FileETag -INode
0
chikuyonok #
Я просто видел несколько докладов/презентаций, где чуваки говорили «да, ETag это хорошо, но вот у нас из-за него дофига запросов мимо кэша, поэтому вырубили».

Да и суть тэгов не в том, чтобы их просто посылать, а посылать правильные значения :)
+1
bolk #
Дык, конечно :) Смысл ETag в том, чтобы он менялся, если меняется контент.
–1
maxcom #
cache-control: private поможет
0
azeffin #
Поправьте пожалуйста концовочку 4го абзаца ;)
0
pashka_r #
Спасибо, исправил.
+1
egorF #
«URL для разных языков один и тот же,»

последний абзац вы именно на этот случай написали?:-)
0
pashka_r #
Тонко, но нет ;)
0
stoune #
Ну вобщем есть старый цыкл статтей
www.xml.com/pub/a/2006/02/01/doing-http-caching-right-introducing-httplib2.html

Ну и в Сагалаева тоже есть на русском.

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