SebWeo.com
Представьте, что вы каждое утро приходите в одно и то же кафе и спрашиваете бариста: «Какой кофе вы варите?». Он перечисляет все меню. На следующее утро вы снова спрашиваете то же, и он снова перечисляет. Это пустая трата времени, правда? Логичнее было бы запомнить тот небольшой перечень доступного кофе и спрашивать его только тогда, когда он изменится.
Именно так работает кэширование в браузере. Без него ваш браузер при каждом посещении страницы вынужден заново загружать каждую картинку, скрипт и стиль. Это медленно и дорого. HTTP-заголовки кэширования — это инструкции, которые сервер дает браузеру: «Запомни этот файл на неделю» или «Проверяй этот файл при каждом визите».
В этой статье я расскажу о том, как правильно настроить эти инструкции, чтобы ваш сайт летал, а сервер не «задыхался» от лишних запросов.
Раньше для кэширования использовали заголовок Expires, но сегодня стандартом де-факто является Cache-Control. Это мощный инструмент, который позволяет очень гибко управлять поведением кэша.
Он состоит из директив. Давайте разберем самые важные из них:
| Директива | Что она означает |
|---|---|
max-age=3600 | Файл считается «свежим» в течение указанного количества секунд (здесь — 1 час). Браузер даже не будет спрашивать сервер об этом файле, пока время не истечет. |
public | Файл может кэшироваться кем угодно: браузером, CDN, прокси-сервером. Идеально для статики. |
private | Файл предназначен для одного пользователя (например, страница профиля). Кэшировать может только браузер, но не CDN. |
no-cache | Внимание, ловушка! Это не значит «не кэшировать». Это значит «кэшируй, но перед каждым использованием спрашивай сервер, не изменился ли файл» (валидация). |
no-store | Вот это действительно «не кэшировать нигде и никогда». Используется для банковских данных и конфиденциальной информации. |
must-revalidate | Когда срок max-age истечет, браузер обязан проверить актуальность файла на сервере, а не использовать старую копию. |
Когда вы используете no-cache или когда истекает время max-age, браузер делает запрос к серверу: «У меня есть картинка, вот ее метка. Она все еще актуальна?». Для этого существуют два заголовка-валидатора:
"33a64df551425fcc55e4d42a148795d9f25f89d4"). Если хеш на сервере совпадает с тем, что есть у браузера, сервер отвечает 304 Not Modified (тело файла не передается).
Настройка зависит от того, какой веб-сервер вы используете. Если вы не уверены, советую прочитать мою статью о разнице между Nginx и Apache.
Добавьте этот код в блок server вашего конфигурационного файла:
# Кэширование статики (картинки, шрифты) на 1 год
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 365d;
add_header Cache-Control "public, no-transform";
}
# Кэширование HTML (не кэшируем или кэшируем с проверкой)
location ~* \.(html)$ {
add_header Cache-Control "no-cache";
}
Если вы используете Apache, добавьте этот код в файл .htaccess в корне сайта. Вам понадобится модуль mod_expires.
<IfModule mod_expires.c>
ExpiresActive On
# картинки
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
# CSS и JS
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
# По умолчанию
ExpiresDefault "access plus 2 days"
</IfModule>
# Дополнительный контроль заголовков
<IfModule mod_headers.c>
<FilesMatch "\.(js|css|xml|gz|html)$">
Header append Vary: Accept-Encoding
</FilesMatch>
</IfModule>
Иногда нужно запретить кэширование конкретной динамической страницы (например, корзины). Это можно сделать прямо в коде:
<?php
// Запрещаем кэширование
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>
max-age=1 год на style.css и измените дизайн, пользователи будут видеть старый дизайн еще год. Решение: меняйте имя файла при обновлении (например, style.v2.css или style.css?v=2).public для приватных данных. Никогда не используйте public для страниц, где есть личные данные пользователя, иначе они могут остаться в кэше публичного прокси.
По моему мнению, настройка заголовков кэширования — это искусство найти баланс. Вы хотите, чтобы пользователь загружал как можно меньше данных (долгий кэш), но при этом всегда видел актуальную версию сайта.
Мой рецепт прост: «агрессивно» кэшируйте статику (картинки, шрифты) с долгим сроком жизни, используйте версионирование файлов для CSS/JS, и будьте осторожны с кэшированием HTML-страниц, используя no-cache для динамического контента.
Очень многие недооценивают то, что у них есть, и переоценивают то, чего у них нет…
Стоит только поверить, что вы можете – и вы уже на полпути к цели Теодор…
Успешный бизнес в 2025 году немыслим без стабильной ИТ-инфраструктуры. От корпоративного сайта до CRM-системы все…
WordPress годами был непревзойденным "монолитом": он отвечал и за удобную админ-панель, и за хранение данных,…
В мире веб-серверов часто говорят о противостоянии Nginx vs Apache. Но что, если бы я…