Кэширование — хранение уже скачанных файлов на устройстве посетителя. Правильно настроенный кэш означает, что вторая и последующие страницы сайта открываются почти мгновенно: браузеру нужен только HTML, а стили, скрипты, шрифты и картинки он берёт с диска.
Управляют этим HTTP-заголовки ответа.
Cache-Control — основной заголовок
Cache-Control: public, max-age=31536000, immutable
- max-age — сколько секунд файл считается свежим (31536000 — год).
- public — можно кэшировать и промежуточным узлам (CDN, прокси); private — только браузеру.
- no-cache — сохранять можно, но перед использованием нужно спросить сервер, не изменился ли файл. Это не «не кэшировать», как думают по названию.
- no-store — не сохранять вообще. Для страниц с личными данными.
- immutable — файл не изменится никогда; браузер не будет перепроверять его даже при обновлении страницы.
ETag и Last-Modified
Отпечаток содержимого и дата изменения. Когда срок свежести истёк, браузер не качает файл заново, а спрашивает: «у меня версия с таким отпечатком, актуальна?» Если да, сервер отвечает 304 Not Modified без тела — экономятся почти все байты.
ETag: "5d8c72a5edda8"
Last-Modified: Wed, 12 Mar 2025 10:23:00 GMT
Expires
Старый заголовок с абсолютной датой. Работает, но Cache-Control: max-age его перекрывает и удобнее. Отдельно задавать не нужно.
Что и на сколько кэшировать
| Тип | Настройка |
|---|---|
| CSS, JS с версией в имени файла | max-age=31536000, immutable |
| Изображения, шрифты, иконки | max-age=2592000 (месяц) и больше |
| CSS и JS без версии в имени | max-age=3600 или no-cache с ETag |
| HTML-страницы | no-cache — контент меняется |
| Личный кабинет, корзина | private, no-store |
Ключевая деталь: версионирование
Долгий кэш безопасен только тогда, когда при изменении файла меняется его имя:
<link rel="stylesheet" href="/build/app.a3f91c.css">
При следующей сборке имя станет другим, браузер увидит новый адрес и скачает новую версию. Без этого приёма долгий max-age опасен: посетители неделями будут видеть старые стили, и «почистите кэш» превратится в стандартный ответ поддержки.
Сборщики (Vite, Webpack) добавляют хеш в имя автоматически. Для сайта без сборки подойдёт параметр в адресе: style.css?v=17 — менять его придётся руками при каждой правке.
Настройка
Nginx:
location ~* \.(css|js|woff2|jpg|png|svg)$ {
expires 30d;
add_header Cache-Control "public";
}
Apache (.htaccess):
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 year"
</IfModule>
Как проверить
- Пункт аудита «Кэширование (заголовки)».
- В браузере:
F12→ Network → любой файл → Response Headers →cache-control. При повторной загрузке страницы в колонке Size должно появиться(memory cache)или(disk cache). - Из консоли:
curl -I https://example.ru/build/app.css | grep -i -E "cache-control|etag|expires"