войти зарегистрироваться

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

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

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

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

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

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

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

  • etag — это, емнип, нововведение http1.1
    а last-modified — соответственно http1.0, оставленное для обратной совместимости
    • Ну у меня бы первый вопрос напросился: а зачем, если уже есть один механизм? Собстенно он и возникал.
      • затем, что он более продвинутый
  • Перенесите, пожалуйста, в блог «Клиентская оптимизация»
  • а вообще информация о языке должна быть частью url
    • Ну это тема для отдельного холивара. Я, например, не вижу в этом никакого смысла. Язык берется из сессии/куков, а если там ничего об этом не сказано, то тот, который просит клиент в заголовках запроса.
      • поисковики так хуже индексят — они же cookie не поддерживают
        • Есть подозрение, что они поддерживают http заголовки.
          • ну, значит, не все заголовки :)
        • А мне кажется, что это даже противоречит лицензии поисковиков.
      • основной принцип хттп, между прочим, это то, что ресурс однозначно определяется урлом. но можно ему не следовать, конечно же, и етаги руками мастерить.
        • Дайте, пожалуйста, пруфлинк.
        • http header vary
      • Ага, а как тогда ссылку дать на страницу на конкретном языке?
        • раскрыть комментарий
          • Уникальной единице информации должен соответствовать уникальный URL. Конкретному URL — строго конкретная единица информации на конкретном языке. Разные языки (разные документы с физически разным содержимым) — разные URL. И дело не в поисковиках, а в простом здравом смысле.
            • Это все замечательно, пока речь идет об информации а не о формах, инструментах и т д.
              К примеру, если в gmail будет отдельная ссылка на каждый язык интерфейса-- это уже выглядит победой теории над здравым смыслом.

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

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

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

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

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

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

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

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

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