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

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

Кэширование - основа производительности веба. Зачем скачивать файл заново, если он не изменился? Браузер хранит копии ресурсов и использует их вместо повторных запросов. На сервере паттерны кеширования - в уроке Redis.

Три фазы HTTP-кеша: первый запрос, использование кеша, ревалидация через ETag

Как работает кэш

Первый запрос:
Браузер → GET /style.css → Сервер
Браузер ← 200 OK + файл + Cache-Control: max-age=3600

Следующие 60 минут:
Браузер → /style.css (из кэша, запрос на сервер НЕ уходит)

Через 60 минут:
Браузер → GET /style.css (If-None-Match: "abc123") → Сервер
Сервер → 304 Not Modified (файл не изменился, тело не отправлено)

Cache-Control - главный заголовок

Сервер управляет кэшированием через заголовок Cache-Control:

Cache-Control: max-age=3600
max-age=N - кэшировать N секунд (3600 = 1 час)
no-cache - кэшировать, но ВСЕГДА проверять с сервером (валидация)
no-store - НЕ кэшировать вообще (конфиденциальные данные)
public - можно кэшировать на CDN и прокси
private - кэшировать только в браузере (персональные данные)
immutable - файл никогда не изменится (нет ревалидации)
must-revalidate - после истечения max-age обязательно проверить с сервером
`no-cache` означает «кэшируй, но проверяй каждый раз». Для полного запрета кэша - `no-store`. Это самая частая путаница.

Типичные стратегии

Статика (JS, CSS, изображения) с хешем в имени:
  Cache-Control: public, max-age=31536000, immutable
  Файл style.a1b2c3.css - имя меняется при обновлении

HTML-страницы:
  Cache-Control: no-cache
  Всегда проверять, но кэш использовать при 304

API-ответы:
  Cache-Control: private, no-cache
  Или no-store для конфиденциальных данных

Чувствительные данные (банк, медицина):
  Cache-Control: no-store

ETag - идентификатор версии

ETag (Entity Tag) - уникальная метка файла. Если файл изменился - ETag меняется.

Первый запрос:
→ GET /style.css
← 200 OK
   ETag: "abc123"
   Cache-Control: no-cache

Второй запрос (проверка):
→ GET /style.css
   If-None-Match: "abc123"

Если файл не изменился:
← 304 Not Modified (без тела - экономия трафика)

Если файл изменился:
← 200 OK
   ETag: "def456"
   (новое тело)

ETag генерируется сервером - обычно хеш содержимого файла.

Last-Modified - дата изменения

Альтернатива ETag - дата последнего изменения:

Первый запрос:
← Last-Modified: Thu, 01 May 2026 10:00:00 GMT

Проверка:
→ If-Modified-Since: Thu, 01 May 2026 10:00:00 GMT
← 304 Not Modified (или 200 с новым файлом)

ETag точнее (работает на уровне содержимого), Last-Modified - проще (работает с датами).

304 Not Modified

304 - специальный статус-код: «файл не изменился, используй кэш». Сервер не отправляет тело ответа - огромная экономия трафика для больших файлов.

Запрос:
GET /bundle.js HTTP/1.1
If-None-Match: "v42"

Ответ:
HTTP/1.1 304 Not Modified
ETag: "v42"
(тело отсутствует)

Хеши в именах файлов

Современные сборщики (Vite, Webpack) добавляют хеш содержимого в имя файла:

style.css      → style.a1b2c3d4.css
app.js         → app.f5e6d7c8.js
logo.png       → logo.9a8b7c6d.png

При изменении файла хеш меняется → новое имя → браузер скачивает новую версию. Для таких файлов можно ставить max-age=31536000 (1 год) - они никогда не устареют.

<!-- HTML всегда свежий (no-cache), ссылается на актуальные файлы -->
<link rel="stylesheet" href="/assets/style.a1b2c3d4.css" />
<script src="/assets/app.f5e6d7c8.js"></script>
HTML получает `no-cache` (всегда проверяется). CSS/JS с хешами - `max-age=31536000, immutable`. При деплое HTML обновляется и ссылается на новые файлы.

Service Worker - кэш на стероидах

Service Worker - JavaScript, который работает между браузером и сетью. Может перехватывать запросы и отдавать ответы из кэша:

Cache-First:       Сначала кэш → если нет, сеть → сохранить в кэш
Network-First:     Сначала сеть → если нет, кэш (для API)
Stale-While-Revalidate: Отдать из кэша сразу + обновить в фоне

Service Worker позволяет работать офлайн (PWA). Но это продвинутая тема - начни с HTTP-кэширования.

Где смотреть кэш в DevTools

Network вкладка показывает:

Size: (disk cache) - файл из кэша на диске
Size: (memory cache) - файл из кэша в памяти
Size: 45.2 kB - скачан с сервера
Status: 304 - сервер подтвердил, что файл не изменился

Checkbox «Disable cache» в DevTools - отключает кэш для отладки (полезно при разработке).

Мини-задание

  • Открой DevTools → Network и найди файл со статусом 304 (или disk cache)
  • Посмотри заголовок Cache-Control у CSS/JS файла
  • Найди ETag в заголовках ответа
  • Включи «Disable cache» в DevTools и перезагрузи - сравни время загрузки
  • Посмотри, используют ли файлы хеши в именах (style.abc123.css)

Зарегистрируйтесь бесплатно, чтобы пройти квиз, решить задание с автопроверкой и вести прогресс.