HTTP кэширование: Cache-Control, ETag, Expires
Зачем нужно HTTP кэширование
HTTP кэширование — один из самых эффективных способов ускорить загрузку сайта. Когда браузер сохраняет копию ресурса локально, повторные запросы обрабатываются мгновенно, без обращения к серверу. Это снижает нагрузку на сервер, уменьшает потребление трафика и значительно улучшает пользовательский опыт.
По данным Google, уменьшение времени загрузки на 100 мс увеличивает конверсию на 1%. Правильно настроенное кэширование может сократить время загрузки повторных визитов на 80-90%.
Основные заголовки кэширования
Cache-Control
Заголовок Cache-Control — главный инструмент управления кэшированием в HTTP/1.1 и новее. Он заменяет устаревший Pragma и имеет приоритет над Expires.
Основные директивы:
public— ресурс может кэшироваться любым промежуточным кэшем (CDN, прокси)private— кэширование только в браузере пользователя (для персонализированных данных)max-age=N— время жизни кэша в секундахs-maxage=N— время жизни для shared-кэшей (CDN), переопределяетmax-ageno-cache— кэшировать можно, но перед использованием нужно валидировать на сервереno-store— запрет кэширования полностью (для конфиденциальных данных)must-revalidate— после истечения TTL обязательна проверка на сервереimmutable— ресурс никогда не изменится (для файлов с хешем в имени)
Пример для статических ресурсов с хешем:
Cache-Control: public, max-age=31536000, immutable
Пример для HTML-страниц:
Cache-Control: no-cache
Пример для API документацию с приватными данными:
Cache-Control: private, no-store
ETag (Entity Tag)
ETag — это уникальный идентификатор версии ресурса. Сервер генерирует хеш содержимого и отправляет его в заголовке ответа:
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
При повторном запросе браузер отправляет If-None-Match с сохранённым ETag. Если ресурс не изменился, сервер отвечает 304 Not Modified без тела ответа, экономя трафик.
Существуют два типа ETag:
- Сильный ETag — байт-в-байт идентичность:
"abc123" - Слабый ETag — семантическая эквивалентность:
W/"abc123"
Last-Modified и If-Modified-Since
Заголовок Last-Modified содержит дату последнего изменения ресурса. Это более простой механизм валидации по сравнению с ETag, но менее точный — точность ограничена одной секундой.
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
При повторном запросе браузер отправляет If-Modified-Since. ETag имеет приоритет над Last-Modified, если присутствуют оба заголовка.
Expires
Устаревший заголовок из HTTP/1.0, задаёт абсолютную дату истечения кэша:
Expires: Thu, 01 Dec 2026 16:00:00 GMT
Проблемы с Expires: зависит от синхронизации часов клиента и сервера, менее гибкий чем Cache-Control. Используйте Cache-Control: max-age вместо него.
Стратегии кэширования по типам ресурсов
HTML-документы
HTML-страницы обычно содержат ссылки на CSS и JS файлы, поэтому должны всегда проверяться на актуальность:
Cache-Control: no-cache ETag: "page-v42"
Это позволяет браузеру кэшировать страницу, но проверять обновления при каждом визите.
CSS, JavaScript, шрифты
Статические ресурсы с хешем в имени файла (например, app.a1b2c3.js) можно кэшировать навсегда:
Cache-Control: public, max-age=31536000, immutable
Без хеша в имени используйте более короткий TTL:
Cache-Control: public, max-age=86400
Изображения
Изображения редко меняются. Для оптимизированных изображений с уникальными URL:
Cache-Control: public, max-age=2592000
Это 30 дней — хороший баланс между кэшированием и возможностью обновления.
API-ответы
Для API с часто меняющимися данными:
Cache-Control: private, no-cache, max-age=0
Для редко обновляемых публичных API:
Cache-Control: public, max-age=300, s-maxage=600
Распространённые ошибки
- no-cache ≠ не кэшировать. Директива
no-cacheразрешает кэширование, но требует ревалидацию. Для полного запрета используйтеno-store. - Одинаковый TTL для всех ресурсов. HTML и статика требуют разных стратегий.
- Отсутствие версионирования. Без хеша или версии в URL пользователи увидят старые CSS/JS после обновления.
- Игнорирование CDN. Без
s-maxageCDN будет использоватьmax-age, что может быть нежелательно. - Кэширование персональных данных как public. Ответы с cookies или персонализацией должны быть
private.
Как проверить настройки кэширования
Проверьте заголовки кэширования вашего сайта с помощью HTTP чекера Enterno.io. Инструмент покажет все анализ заголовков ответа, включая Cache-Control, ETag, Expires и Last-Modified. Это поможет убедиться, что кэширование настроено правильно.
В Chrome DevTools на вкладке Network столбец Size покажет (disk cache) или (memory cache) для кэшированных ресурсов, а код 304 — для успешно ревалидированных.
Рекомендуемая конфигурация nginx
# HTML — всегда проверять обновления
location ~* \.html$ {
add_header Cache-Control "no-cache";
}
# Статика с хешем — кэш навсегда
location ~* \.(js|css)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
# Изображения — кэш на 30 дней
location ~* \.(jpg|jpeg|png|gif|webp|svg|ico)$ {
add_header Cache-Control "public, max-age=2592000";
}
# Шрифты — кэш на год
location ~* \.(woff2?|ttf|eot)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Access-Control-Allow-Origin "*";
}
Итоги
Правильное HTTP кэширование — это баланс между скоростью и актуальностью контента. Используйте Cache-Control как основной инструмент, ETag для валидации, и версионирование файлов для безопасного долгосрочного кэширования. Регулярно проверяйте заголовки ваших ресурсов, чтобы убедиться в корректности настроек.
Проверьте ваш сайт прямо сейчас
Проверить →