Как работает HTTP caching. ETag, Cache-Control, stale-while-revalidate простыми словами
Когда сайт начинает тормозить под нагрузкой, многие первым делом смотрят на базу данных, 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 происходит так:
- Пользователь получает старую копию мгновенно
- Система тихо обновляет данные в фоне
- Следующий пользователь уже увидит свежую версию
Это особенно полезно для:
- 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-системах грамотное кэширование напрямую влияет не только на скорость сайта, но и на стабильность всей инфраструктуры.
Настроить мониторинг за 30 секунд
Надежные оповещения о даунтаймах. Без ложных срабатываний