Кэширование: стратегии для скорости и выживания под нагрузкой
Кэш — единственное «ускорение», которое не требует менять архитектуру: правильно настроенный кэш даёт рост скорости в 3–10 раз и защищает сервер от пиков. Но кэш без стратегии — это «залоги»: устаревшие цены, пустые корзины и неработающие комментарии. Разбираем уровни кэша и как их комбинировать.
Уровни кэша
| Уровень | Где живёт | Что кэширует | Выигрыш |
|---|---|---|---|
| Браузерный | У пользователя | CSS, JS, картинки, шрифты | Повторные визиты мгновенно |
| CDN | Сеть доставки (Cloudflare и др.) | Статика, публичные страницы | Скорость из ближайшего города |
| Прикладной | Внутри приложения | Ответы, шаблоны, данные | Сервер почти не работает |
| БД | В базе/Redis/Memcached | Частые запросы SQL | БД не «падает» на пиках |
| HTTP-заголовки | Протокол | Правила TTL для всех выше | Контроль всей цепочки |
HTTP-кэширование: основа всего
Правильные заголовки — фундамент. Без них ни браузер, ни CDN не знают, что можно хранить:
// Статика: долгий кэш + невалидация по содержимому
Cache-Control: public, max-age=31536000, immutable
// (имя файла меняется при сборке: app.1a2b3c.js)
// HTML: короткий кэш с проверкой
Cache-Control: public, max-age=0, must-revalidate
ETag: "abc123"
// Личные данные — не кэшировать
Cache-Control: private, no-store
- Immutable для бандлов с хешем в имени — и скорость, и безопасность обновлений.
- ETag/Last-Modified — браузер проверяет «не изменилось ли» и грузит с сервера только изменения.
- no-store для личного: корзина, кабинет, оплата — никогда не кэшировать.
CDN и страницы
Статика уходит на CDN сама. Сложнее с HTML: если сайт не персонализирован (лендинг, блог, каталог без корзины), кэшируйте страницы целиком — например, в Cloudflare через Cache Rules:
// Правило: кэшировать все страницы /blog/* и /catalog/* на 1 час
Cache Everything + Edge TTL: 3600s + Browser TTL: 600s
// и Purge по триггеру при публикации статьи
Типовая схема: CDN + короткий TTL (5–60 минут) для публичных страниц. При пике (реклама, новости) сервер выдерживает в 10 раз больше трафика.
Прикладной кэш (Redis, in-memory)
Для динамики — кэшируйте результаты тяжёлых операций в приложении:
// Node.js + Redis: кэш с TTL 5 минут
async function getPrice(productId) {
const key = 'price:' + productId;
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const price = await db.queryPrice(productId); // дорогой SQL
await redis.set(key, JSON.stringify(price), 'EX', 300);
return price;
}
- Кэшируйте: частые SQL, расчёты, шаблоны, ответы внешних API, сессии.
- Инвалидация: TTL для «просто данных»; событийная очистка для критичных (цена изменилась → удалили ключ).
- Имена ключей с версией схемы — иначе старые данные ломают новый код.
Кэширование в CMS
Для WordPress/1С-Битрикс и т.п. — это плагины и встроенные механизмы: WP Super Cache/W3 Total Cache/Rocket, Memcached/Redis-объектный кэш. Правило: включайте по одному уровню и замеряйте, иначе плагины начинают конфликтовать.
Главные ловушки
| Ошибка | Симптом | Решение |
|---|---|---|
| Кэш корзины/кабинета | Чужие данные, пустые корзины | no-store для личного |
| Долгий TTL на HTML | Устаревшие цены, новости | Purge при публикации, короткий TTL |
| Кэш после A/B-теста | Половина юзеров видит «старую» версию | Разделение по cookie/варианту |
| Кэш форм/комментариев | Спам-страницы, дыры безопасности | Исключить POST/динамику |
| Кэш без инвалидации | «Почему не обновилось?!» | Событийная очистка + TTL-потолок |
«Кэш — это компромисс между скоростью и свежестью, и он должен быть осознанным: каждый уровень хранит данные до тех пор, пока они не устареют, а устаревание объявляется TTL или событием. Без стратегии кэш — источник багов, с стратегией — ускоритель в разы» — практика веб-производительности, 2026.
Начните с заголовков Cache-Control (статика immutable, HTML с ETag), затем CDN и кэш страниц с TTL. Измеряйте время ответа до и после — разница вас удивит.