Понимание условного кэширования HTTP с использованием ETag и Last-Modified

Кэширование HTTP позволяет сэкономить время и трафик, поскольку ресурсы загружаются заново только в том случае, если они действительно изменились. О ETag и Last-Modified Я проверяю с помощью условного запроса, отвечает ли сервер кодом 304 Not Modified, что позволяет значительно сократить объем передаваемых данных и нагрузку на сервер.

Центральные пункты

Следующие основные тезисы показывают, на что я обращаю внимание при использовании условного кэширования с ETag и Last-Modified внимание.

  • Меньше трафика: При неизменности файлов возвращается код 304, а не весь текст сообщения — это заметно снижает объем передаваемых данных и задержку.
  • Лучшая производительность: Сокращение времени ожидания положительно сказывается на пользовательском опыте (UX) и показателях Core Web Vitals, что SEO помогает.
  • Два механизма: Last-Modified/If-Modified-Since и ETag/If-None-Match обеспечивают надежную проверку кэша.
  • Управление кэшем: Директивы определяют сроки хранения, обновление и поведение данных в промежуточных кэшах.
  • Комбинация: В совокупности эти два метода обеспечивают высокую точность и простые резервные варианты.

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

Условное кэширование HTTP: как проверить срок действия

При повторном запросе клиент отправляет помимо GET дополнительные заголовки, которые я обрабатываю на стороне сервера. Если ресурс имеет тот же ETag Если содержимое совпадает с кэшем (If-None-Match), я возвращаю 304 Not Modified без тела. Если временная метка не изменилась (If-Modified-Since), сервер также отвечает кодом 304. Если день или дата больше не совпадают, я отправляю 200 OK с новым содержимым и обновленным Last-Modified и ETag. Таким образом я экономлю трафик, поддерживаю актуальность кэша и обеспечиваю заметно более быструю загрузку страниц.

Last-Modified и If-Modified-Since в повседневной практике

Заголовок Last-Modified Я использую фактическую дату изменения файла, например, из файловой системы. Если позже поступает запрос с параметром If-Modified-Since, а ресурс с тех пор не изменился, я отвечаю кодом 304. Этот подход прост, понятен и идеально подходит для статических ресурсов, таких как CSS, JS или изображения. Ограничения возникают из-за секундной сетки HTTP-меток времени и ситуаций, в которых контент логически изменяется, но четкой даты изменения файла не существует. Там, где Last-Modified достигает своих пределов, его дополняет ETag контроль.

ETag и If-None-Match в динамических системах

A ETag Я генерирую его в виде хеша, идентификатора версии или на основе столбца базы данных, который отмечает изменения состояния. При повторном доступе браузер отправляет If-None-Match, я сравниваю тег с моим текущим значением и отвечаю соответственно 304 или 200. Это сравнение распознает любое значимое изменение контента, не полагаясь на временные метки файлов. Особенно в случае API, составных страниц или персонализированных фрагментов это дает очень точные результаты. Важно, чтобы я поддерживал ETag в кластерных средах, чтобы ни один сервер случайно не использовал другой День производится.

Правильное сочетание параметров Cache-Control

С Управление кэшем Я определяю, как долго контент считается актуальным без повторного запроса и когда браузер должен повторно проверять его. Я устанавливаю подходящие значения max-age в зависимости от частоты обновлений и использую must-revalidate, если устаревшие данные могут иметь критические последствия. Для файлов с версиями подходит длительный срок действия, в то время как часто меняющиеся ответы имеют более короткий срок действия и затем могут быть аккуратно проверены с помощью ETag или даты. Таким образом, я сочетаю короткие времена отклика с правильной актуальностью. Те, кто хочет углубиться в тему, найдут множество примеров на Стратегии управления кэшем, которые я использую на практике.

Пошаговая инструкция по выполнению Conditional GET

При первом запросе сервер отправляет ответ 200 OK с параметром Cache-Control, Last-Modified и ETag, браузер сохраняет все эти данные. При следующем посещении срок хранения в кэше определяет, требуется ли повторная проверка. Если она необходима, браузер отправляет запрос с помощью If-None-Match и/или If-Modified-Since. Если значения совпадают с текущим состоянием, я отправляю 304 Not Modified, и клиент продолжает использовать свой кэш. Если они больше не совпадают, следует 200 OK с новым телом и обновленными Данные валидации.

Сравнение: ETag и Last-Modified

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

Аспект Last-Modified ETag Подсказка
Идентичность Время последнего изменения Хеш содержимого или идентификатор версии Время vs. идентификатор на основе содержимого
Обнаружение изменений С секундным разрешением, косвенно Ориентированный непосредственно на содержание ETag распознает мельчайшие Различия
внедрение Очень просто, достаточно файловой системы Требует генерации и согласованности Кластеры нуждаются в одинаковых ETags
Используйте Статические ресурсы Динамические ответы Этот набор подходит для многих случаи с сайта
Ответы 304 при неизменной метке времени 304 при одинаковом теге 200 при внесении изменений с новым Значение

Практика: эффективная доставка статических ресурсов

Статические файлы, такие как CSS, JS и изображения, редко меняются и подходят для длительного max-age-Время. Для файлов с версиями я устанавливаю длительные сроки — до одного года — и помечаю их как неизменяемые, чтобы браузер загружал их без повторных запросов. Для ресурсов без версий я выбираю более короткие сроки и полагаюсь на повторную проверку с помощью ETag и Last-Modified. Так я избегаю устаревшего контента и снижаю трафик. Я слежу за тем, чтобы не Саботаж заголовка кэша таким образом я добиваюсь высокой точности поиска в кэше.

Практика: API и динамические страницы

Что касается API, я обычно делаю ставку на ETags, который я формирую на основе сериализованного результата или столбца версии. Если запись изменяется, я генерирую новый тег, и клиенты сразу это распознают. Для контента с ненадежной временной меткой я часто отказываюсь от Last-Modified, чтобы не создавать ложного впечатления свежести. В дополнение к этому я управляю сроком жизни с помощью Cache-Control и принудительно запускаю повторную проверку по истечении срока. Таким образом, я надежно поддерживаю свежесть данных, не увеличивая при этом размер ответов без необходимости.

Тестирование и мониторинг коэффициента попадания в кэш

Я проверяю такие заголовки, как ETag, Last-Modified, If-None-Match и If-Modified-Since в инструментах разработчика. При этом я обращаю внимание на коды ответов, в частности на разницу между 304 и 200, чтобы оценить эффективность моей повторной проверки. Если 304 встречается редко, я корректирую Cache-Control, сроки действия и генерацию ETag. Логи и метрики показывают мне, какие пути дают неоправданно большие ответы. Для комплексных улучшений я с удовольствием использую Пакет Conditional-Requests, который объединяет настройку и тестирование.

Архитектура хостинга и ловушки ETag

В конфигурациях с несколькими серверами необходимо ETag независимо от экземпляра, иначе распознавание не сработает. Я слежу за тем, чтобы все узлы использовали одну и ту же логику и один и тот же ключ для генерации. Обратные прокси или CDN не должны изменять ETag и должны правильно передавать заголовок Condition. При развертывании с отпечатками ресурсов я избегаю пересчета ETag на стороне сервера, если файл уже имеет URL с версией. Единые правила предотвращают несогласованные ответы и поддерживают высокий показатель попаданий в кэш.

Свежесть против валидации: точное использование директив

Я провожу четкое различие между Свежесть (как долго кэш может использовать копию без запроса?) и Валидация (как проверить, действует ли она?). О Управление кэшем я точно настраиваю оба параметра: max-age определяет срок службы на стороне клиента, s-maxage для общих кэшей, таких как прокси-серверы. публичный позволяет осуществлять кэширование в разделённых кэшах, частный ограничивает его конечным браузером. must-revalidate вызывает запрос на подтверждение по истечении времени, в то время как неизменяемый предотвращает ненужные повторные проверки для ресурсов с версиями. no-cache не запрещает кэширование, а требует постоянной повторной проверки; без магазина в то же время полностью запрещает сохранение. Старые Срок действия:-Header я использую только в качестве резервного варианта, а всю логику последовательно переношу в Cache-Control. А если мне нужно смягчить последствия сбоев, то помогают stale-while-revalidate и stale-if-error, чтобы делиться контентом, срок действия которого истек, пока я в фоновом режиме обновляю страницу или устраняю ошибки.

Сильные и слабые ETag, сжатие и варианты

Я сознательно делаю различие между сильными и слабыми валидаторами. Сильные ETags идентифицировать точно такое же представление на уровне байтов — идеально, если я также Запросы по диапазону хочет эффективно обслуживать. Слабые ETags (Префикс W/) достаточно, если достаточно семантического соответствия, например, в случае небольших, несущественных изменений форматирования. Важно правильно обращаться с Компрессия: Если я предоставляю контент как в формате gzip, так и в формате Brotli, один и тот же ETag не может применяться ко всем вариантам. Либо я формирую тег на основе несжатого варианта и дополнительно устанавливаю соответствующий Vary: Accept-Encoding, либо я генерирую для каждого варианта одинаковые, но разные ETag. Таким образом я предотвращаю ложные срабатывания и ответы 200, которые на самом деле должны быть 304. При If-Range Я сочетаю запросы на проверку срока действия с валидатором: если ETag или дата совпадают, я отвечаю кодом 206 (Partial Content); в противном случае я возвращаю код 200 с полным телом, чтобы у клиента была согласованная основа.

В совершенстве овладеть навыками работы с Vary-Header и Content-Negotiation

Всякий раз, когда сервер предоставляет различные представления в зависимости от запроса, я устанавливаю Vary верно. Типичными примерами являются Принять кодирование (сжатие), Accept-Language (локализация) или определенные флаги функций. Я стараюсь не использовать такие нестабильные заголовки, как Пользовательский агент или даже Печенье изменять, так как это значительно снижает коэффициент попадания в кэш. Там, где требуется персонализация, я помечаю ответы как частный или без магазина и четко отделяю их от ресурсов, доступных для кэширования. Важно: вариации влияют и на ETag — каждой вариации нужен свой собственный, соответствующий валидатор. Таким образом я гарантирую, что браузеры, прокси-серверы и CDN будут использовать одну и ту же логику, и ни одна вариация не будет случайно смешана с другой.

Условные запросы, выходящие за рамки GET

Условные запросы работают не только при чтении. Для методов записи я использую Если совпало или If-Unmodified-Sinceдля того чтобы пропущенные обновления предотвратить. Если при выполнении запроса PUT или DELETE клиент передает последний ETag, полученный Если совпало с, я выполняю изменение только в том случае, если состояние сервера осталось прежним — в противном случае я отвечаю 412 Нарушение предварительного условия. Кроме того, для обеспечения дисциплины клиентов сервер может 428 Требуется выполнение предварительного условия установить. Для быстрых проверок без использования Body я использую HEAD, который возвращает те же заголовки, что и запрос GET; идеально подходит, если я хочу протестировать метаданные. А в случае 304-В ответах я повторно указываю все заголовки, имеющие отношение к кэшированию (Cache-Control, ETag, Expires, Last-Modified), чтобы клиент обновил свои метаданные без передачи тела сообщения.

Безопасность, защита данных и соответствие нормативным требованиям

Я не сохраняю персональные данные или конфиденциальную информацию в общедоступном кэше. Здесь я использую Контроль кэша: частный или без магазина, чтобы браузер или вообще никакой экземпляр не сохранял контент. Будьте осторожны с учетными записями пользователей и панелями управления: ответы с Установите печенье или Авторизация не должны случайно быть доступны для кэширования. Сами ETag могут использоваться в качестве средства отслеживания, если они остаются неизменными в течение длительного времени. Я решаю эту проблему, активно используя валидаторы только там, где кэширование действительно необходимо, и отключая их для пользовательских маршрутов или сокращая их срок действия. Таким образом, я совмещаю производительность с требованиями конфиденциальности.

Детали реализации и затраты на производительность

Создание ETag не должно обходиться дороже, чем приносимая им польза. Для больших файлов или ресурсоемких рендерингов я сохраняю тег вместе с метаданными (контрольная сумма файла, хеш сборки, база данных—версия строки) и не повторяю его при каждом запросе. В случае составных страниц помогает Стратегия составления версий: Я формирую ETag из стабильных частичных ETag (например, шаблон, фрагмент данных, конфигурация), чтобы небольшие изменения приводили к получению конкретного, но воспроизводимого нового значения. В кластерах я синхронизирую логику генерации в общей библиотеке и проверяю ее в CI, чтобы ни один экземпляр не отклонялся. Для очень больших блобов я использую быстрые контрольные суммы (CRC64) или сохраняю хеши сборки, вместо того чтобы хешировать тело на лету. Там, где не требуется абсолютное байтовое совпадение, достаточно недостоверные ETag в качестве прагматичного компромисса.

Распространенные ошибки и как их избежать

  • Случайные ETag: Если теги генерируются заново при каждом запросе, любая повторная проверка теряет смысл. Я обеспечиваю детерминированные значения, которые меняются только при реальных изменениях.
  • Неправильное сочетание директив: без магазина Использование ETag бесполезно — браузер все равно не сохраняет данные. Я выбираю фиксированные комбинации для обеспечения нужного поведения.
  • Чрезмерное варьирование: Вариации в поле «Cookie» или «User-Agent» приводят к разбиению кэша. Я ограничиваю использование Vary только реальными изменениями представления.
  • Ловушки сжатия: Использование одного и того же ETag для gzip и br приводит к ложным срабатываниям. Я четко связываю ETag с конкретным вариантом и правильно задаю Vary.
  • Смещение времени: Неточные системные часы сервера искажают значение Last-Modified. Я синхронизирую источники времени, чтобы параметр If-Modified-Since работал правильно.
  • Ошибочное использование атрибута no-cache: Многие читают как „не кэшировать“. На самом деле имеется в виду „всегда перепроверять“. Для настоящего запрета я использую без магазина.

Устранение неполадок, метрики и рабочие процессы

Для поиска неисправностей я запускаю вкладку «Сеть»: все в порядке Управление кэшем? Возникает при реабилитации 304 вместо 200? Подойдет ETag и Last-Modified Сколько времени проходит между запросом и ответом? Я проверю Vary, чтобы проверить, правильно ли распознаны варианты. В журналах я просматриваю Попал/Промах-выводить коэффициенты, показатели 304 и средний размер ответа по каждому пути. При увеличении показателя 304 объем данных и TTFB, как правило, заметно снижаются. В нагрузочных тестах я моделирую повторные запросы, чтобы измерить затраты на повторную валидацию, а не на передачу данных. При обнаружении аномалий я постепенно устраняю факторы, мешающие работе: Set-Cookie, слишком строгие правила Vary, противоречивые заголовки, такие как Pragma. Так я быстро нахожу узкое место, которое снижает частоту обращений.

Service Worker как дополнительный уровень кэша

Если я использую сервисный рабочий процесс, то применяю его в качестве дополнительного, а не конкурирующего уровня. Я позволяю ему выполнять те же Управление кэшем-учитывайте сигналы и сочетайте такие стратегии, как stale-while-revalidate с использованием HTTP-проверки по ETag и Last-Modified. В автономном режиме рабочий процесс может предоставлять временно устаревшие ресурсы и повторно проверять их в фоновом режиме. Важно, чтобы он правильно передавал заголовки условий, иначе я теряю преимущества 304 на сетевом участке. Таким образом, сценарии PWA также извлекают выгоду из корректного HTTP-кеширования, вместо того чтобы обходить его механизмы.

Эффективность SEO и Core Web Vitals

Улучшение оперативности ответов UX и сигналы пользователей, что благоприятно сказывается на рейтингах. Особенно выигрывают постоянные посетители, поскольку их браузеры загружают многие файлы напрямую из кэша или подтверждают их с помощью кода 304. Такая меньшая задержка положительно влияет на показатели FCP, LCP и TTFB, которые я снижаю с помощью целенаправленной повторной проверки. Кроме того, сервер экономит вычислительное время, которое я могу использовать для пиковых нагрузок или ресурсоемких запросов. Таким образом, я сохраняю высокую производительность, а контент доставляется корректно и своевременно.

Резюме: Мой план действий

Я полагаюсь на четкое Комбинация на основе Cache-Control, Last-Modified и ETag. Для статических ресурсов я выбираю длительные сроки хранения и использую повторную проверку, если файлы не имеют версий. Для динамических ответов я генерирую надежные ETag и поддерживаю согласованность кластеров. Затем с помощью инструментов, метрик и логов я проверяю, достаточно ли часто возникают 304, и корректирую настройки. Таким образом я обеспечиваю быструю доставку, меньшую нагрузку и лучший пользовательский опыт за счет эффективного Кэширование HTTP.

Текущие статьи

Центр обработки данных с сетевыми серверами баз данных для топологии репликации
Базы данных

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

Подробное руководство по топологиям репликации баз данных в хостинге: узнайте, как правильно спланировать конфигурацию репликации для обеспечения производительности, высокой доступности и масштабируемости ваших баз данных. Особое внимание уделяется топологиям репликации баз данных для современных веб-проектов.

Схематическое изображение условного кэширования HTTP с использованием ETag и Last-Modified в среде веб-сервера
Веб-сервер Plesk

Понимание условного кэширования HTTP с использованием ETag и Last-Modified

Узнайте, как работает условное кэширование HTTP с использованием ETag и Last-Modified, как осуществляется проверка кэша браузера и как с помощью этого оптимизировать время загрузки, пропускную способность и нагрузку на сервер.