Как работает HTTP caching. ETag, Cache-Control, stale-while-revalidate простыми словами

9 минут чтения
Средний рейтинг статьи — 4.8

Когда сайт начинает тормозить под нагрузкой, многие первым делом смотрят на базу данных, backend или сеть. Но в огромном количестве случаев проблему можно решить намного проще — правильно настроив HTTP-кэширование.

Браузеры, CDN, reverse proxy и сами backend-приложения умеют сохранять ответы и не запрашивать их заново при каждом открытии страницы. Это снижает нагрузку на сервер, ускоряет загрузку сайта и уменьшает расход трафика.

В этой статье разберёмся, как работает HTTP caching, что делают заголовки Cache-Control и ETag, а также зачем нужен stale-while-revalidate.

Что вообще происходит при HTTP-кэшировании

Когда браузер получает ответ от сервера, он может сохранить его локально:

  • HTML-страницу
  • CSS и JavaScript
  • изображения
  • JSON API-ответы
  • шрифты

При следующем запросе браузер решает:

  • использовать локальную копию
  • проверить, изменилась ли версия на сервере
  • полностью скачать ресурс заново

Решение зависит от HTTP-заголовков, которые сервер отправил ранее.

Простейший пример:

Cache-Control: max-age=3600

Это означает:

  • ответ можно хранить 3600 секунд
  • в течение этого времени браузер не будет обращаться к серверу

Если пользователь обновит страницу через 10 минут, файл загрузится мгновенно из локального кэша.

Почему кэширование критично для производительности

Без кэширования браузер вынужден постоянно делать одинаковые запросы:

  • повторно скачивать CSS
  • заново получать JavaScript
  • снова загружать логотипы и изображения
  • каждый раз дёргать API

На небольшом сайте это может быть незаметно. Но при высокой посещаемости отсутствие кэша превращается в огромную лишнюю нагрузку.

Особенно сильно это влияет на:

  • CDN и edge-кэширование
  • API под мобильные приложения
  • frontend на React, Next.js, Vue
  • высоконагруженные панели мониторинга
  • статические ресурсы

В системах мониторинга это хорошо видно по:

  • росту RPS
  • увеличению latency
  • скачкам bandwidth
  • перегрузке backend-сервисов

Например, если dashboard опрашивает API каждые несколько секунд без кэша, это может создать тысячи лишних запросов даже при небольшом количестве пользователей.

Cache-Control — главный заголовок управления кэшем

Сегодня именно Cache-Control считается основным механизмом HTTP-кэширования.

Самые важные директивы:

Cache-Control: max-age=3600

Ресурс считается свежим 1 час.

Cache-Control: no-cache

Браузер обязан проверять актуальность ресурса перед использованием.

Важно: no-cache не запрещает кэширование. Он требует revalidation.

Cache-Control: no-store

Вообще запрещает хранить ответ.

Обычно используется для:

  • банковских страниц
  • личных кабинетов
  • чувствительных данных
  • одноразовых токенов
Cache-Control: public

Разрешает кэшировать ответ даже CDN и proxy.

Cache-Control: private

Кэшировать можно только в браузере пользователя.

Что такое ETag

ETag — это идентификатор версии ресурса.

Пример:

ETag: "a7c9-8912"

Когда браузер повторно обращается к серверу, он отправляет:

If-None-Match: "a7c9-8912"

Сервер сравнивает текущую версию ресурса:

  • если файл не изменился — возвращает HTTP 304 Not Modified
  • если изменился — отправляет новый контент

Это позволяет:

  • экономить трафик
  • не передавать одинаковые данные
  • ускорять повторные запросы

При ответе 304 сервер фактически говорит:

«У тебя уже есть актуальная версия, используй её».

Чем ETag отличается от max-age

Это очень важный момент.

max-age отвечает за freshness.

То есть:

«Можно ли использовать локальную копию без проверки?»

ETag отвечает за validation.

То есть:

«Изменился ли ресурс с прошлого запроса?»

Обычно они работают вместе.

Например:

Cache-Control: max-age=3600
ETag: "v2-file"

В течение часа браузер вообще не обращается к серверу.

После истечения max-age браузер делает revalidation через If-None-Match.

Это намного эффективнее, чем каждый раз скачивать файл полностью.

stale-while-revalidate — кэширование без задержек

Директива stale-while-revalidate появилась позже и сильно улучшила UX.

Пример:

Cache-Control: max-age=60, stale-while-revalidate=300

Что это означает:

  • первые 60 секунд кэш считается свежим
  • следующие 300 секунд можно использовать устаревшую версию
  • при этом браузер или CDN параллельно обновит ресурс в фоне

Без stale-while-revalidate пользователь после истечения max-age может ждать новый запрос к серверу.

С stale-while-revalidate происходит так:

  1. Пользователь получает старую копию мгновенно
  2. Система тихо обновляет данные в фоне
  3. Следующий пользователь уже увидит свежую версию

Это особенно полезно для:

  • API
  • CDN
  • SSR-приложений
  • dashboards
  • часто обновляемого контента

По сути, stale-while-revalidate уменьшает latency и делает интерфейс визуально быстрее.

Почему неправильный кэш ломает приложения

Кэширование кажется простой темой, пока не начинается production.

Типичные ошибки:

  • API-кэш для авторизованных пользователей
  • слишком большой max-age
  • отсутствие versioning для JS/CSS
  • кэширование HTML там, где данные часто меняются
  • no-store вообще везде

Особенно опасна ситуация, когда frontend получает старый JavaScript после деплоя.

Поэтому production-сборки обычно используют versioned filenames:

app.8f31ab.js
styles.91aa22.css

При изменении файла меняется hash — браузер скачивает новую версию автоматически.

Как CDN используют HTTP caching

CDN вроде Cloudflare или Fastly активно используют Cache-Control.

Если backend правильно настроен:

  • ответы сохраняются на edge-нодах
  • пользователи получают контент ближе к себе
  • origin-сервер получает меньше нагрузки

Для статики это может снизить количество запросов к backend в десятки или сотни раз.

Но важно понимать:

  • CDN тоже подчиняется cache headers
  • ошибки в заголовках быстро масштабируются
  • неправильный public cache может утечь между пользователями

Поэтому кэширование API с авторизацией требует особой осторожности.

Как проверять кэширование

Самый простой способ — curl.

Например:

curl -I https://example.com

Можно увидеть:

Cache-Control: max-age=3600
ETag: "abc123"
Age: 120

В браузере удобно использовать вкладку Network в DevTools.

Там видно:

  • cached response
  • 304 Not Modified
  • размер ответа
  • время загрузки
  • hit/miss CDN-кэша

Для production-сервисов полезно мониторить:

  • cache hit ratio
  • latency
  • bandwidth
  • origin requests
  • CDN offload

Плохой cache hit ratio часто означает:

  • неправильные заголовки
  • отсутствие кэширования
  • слишком короткий TTL
  • постоянные cache misses

Итоги

HTTP caching — один из самых дешёвых способов ускорить сайт и снизить нагрузку на инфраструктуру.

Правильное использование Cache-Control, ETag и stale-while-revalidate позволяет:

  • уменьшить latency
  • сократить трафик
  • снизить RPS на backend
  • ускорить frontend
  • разгрузить CDN и origin

При этом важно понимать разницу между freshness и validation.

max-age отвечает за срок жизни кэша, ETag — за проверку актуальности, а stale-while-revalidate помогает обновлять данные без задержек для пользователя.

В production-системах грамотное кэширование напрямую влияет не только на скорость сайта, но и на стабильность всей инфраструктуры.

9 минут чтения
Средний рейтинг статьи — 4.8

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний