Средний

HTTP-кэширование

Урок 2 из 5 в курсе Кэширование в backend-разработке

Содержание курса (2/5)

HTTP-кэширование

HTTP-кэш — встроенный механизм браузера и CDN. Заголовки Cache-Control, ETag и Last-Modified позволяют серверу управлять кэшированием без единой строки на клиенте.

Почему это важно: Правильные HTTP-заголовки кэширования могут снизить нагрузку на сервер на 50–80% для статических и полустатических данных. Это бесплатная оптимизация, которая работает на каждом уровне: браузер, прокси, CDN.

Главная идея

Сервер сообщает клиенту через заголовки, как долго хранить ответ (Cache-Control), и даёт метку версии (ETag). При повторном запросе клиент может спросить: «У меня версия X — она ещё актуальна?» (conditional request).

Как это выглядит на практике

  1. Клиент запрашивает GET /api/products
  2. Сервер возвращает ответ с заголовками Cache-Control: max-age=300 и ETag: "abc123"
  3. Браузер сохраняет ответ в HTTP-кэше
  4. Через 2 минуты — повторный запрос: браузер берёт из кэша, запрос на сервер не уходит
  5. Через 6 минут (TTL истёк) — браузер отправляет запрос с If-None-Match: "abc123"
  6. Если данные не изменились — сервер отвечает 304 Not Modified (без тела)
  7. Браузер использует кэшированную версию ещё на 300 секунд

Примеры кода

HTTP-кэширование в Rails

class ProductsController < ApplicationController
  def index
    @products = Product.published.order(:updated_at)

    # ETag на основе содержимого
    if stale?(etag: @products, last_modified: @products.maximum(:updated_at))
      # Этот код выполнится только при изменении данных
      render json: @products
    end
    # Если ETag совпадает — Rails автоматически вернёт 304
  end

  def show
    @product = Product.find(params[:id])

    # Для статического контента — агрессивный кэш
    expires_in 1.hour, public: true
    render json: @product
  end
end

Основные заголовки кэширования

# Кэшировать 5 минут, разрешить CDN кэшировать
Cache-Control: public, max-age=300

# Не кэшировать (личные данные, корзина)
Cache-Control: no-store

# Всегда проверять свежесть (conditional request)
Cache-Control: no-cache

# ETag — хеш содержимого
ETag: "5d8c72a5edfc8"

# Последнее изменение
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT

# Conditional request от клиента
If-None-Match: "5d8c72a5edfc8"
If-Modified-Since: Wed, 21 Oct 2024 07:28:00 GMT

Что происходит под капотом

  • max-age считается с момента генерации ответа, а не с момента получения клиентом
  • public — CDN и прокси могут кэшировать, private — только браузер конечного пользователя
  • no-cache не запрещает кэширование — он требует обязательной ревалидации перед использованием
  • no-store полностью запрещает сохранение — используйте для конфиденциальных данных
  • 304 Not Modified — тело не передаётся, экономя трафик и время парсинга

Типичные ошибки и заблуждения

  • «no-cache = не кэшировать» — нет, no-cache означает «кэшируй, но проверяй свежесть каждый раз». Для полного запрета — no-store
  • «ETag решает все проблемы» — ETag требует запроса к серверу для проверки, max-age позволяет избежать запроса вообще
  • «Кэширование API не нужно» — для справочных данных (каталоги, конфигурации) HTTP-кэш даёт значительный выигрыш

Ключевые выводы

  • Cache-Control: max-age — время жизни в секундах, public/private — кто может кэшировать
  • ETag + conditional request = экономия трафика при неизменённых данных (304 Not Modified)
  • no-store для конфиденциальных данных, no-cache для обязательной ревалидации

Термины урока

{:term=>"ETag", :definition=>"Entity Tag — уникальный идентификатор версии ресурса, обычно хеш содержимого"}
{:term=>"Conditional request", :definition=>"Запрос с заголовком If-None-Match или If-Modified-Since, позволяющий серверу ответить 304 без тела"}
{:term=>"CDN", :definition=>"Content Delivery Network — сеть серверов, кэширующих контент ближе к пользователям"}

Связь с работой backend-разработчика

HTTP-кэширование — единственный вид кэша, который работает без дополнительной инфраструктуры. Правильные заголовки Cache-Control и ETag в вашем API могут снизить нагрузку на сервер без Redis и Memcached.

Мини-разбор реальной ситуации

API каталога товаров обрабатывал 5 000 запросов в минуту. После добавления Cache-Control: public, max-age=60 и ETag CDN начал обслуживать 80% запросов, не обращаясь к серверу. Нагрузка на бэкенд упала до 1 000 запросов в минуту.

Что запомнить

  • max-age — сколько секунд хранить без проверки, ETag — метка версии для conditional requests
  • public для CDN, private для персональных данных, no-store для секретных
  • 304 Not Modified = данные не изменились, используй кэш

Итог

HTTP-кэширование — мощный бесплатный инструмент. Грамотная настройка Cache-Control и ETag снижает нагрузку на сервер, экономит трафик и ускоряет ответы без дополнительной инфраструктуры.

Комментарии к уроку

Войдите, чтобы оставить комментарий.

Пока нет комментариев — будьте первым.