HTTP-кэширование
HTTP-кэширование
Кэширование - основа производительности веба. Зачем скачивать файл заново, если он не изменился? Браузер хранит копии ресурсов и использует их вместо повторных запросов. На сервере паттерны кеширования - в уроке Redis.
Как работает кэш
Первый запрос:
Браузер → 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 обязательно проверить с сервером
Типичные стратегии
Статика (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>
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)