Что такое SWR в одном абзаце
Stale‑while‑revalidate — это директива HTTP‑кэша, которая разрешает edge‑узлу отдать устаревший ответ пользователю и одновременно сходить за свежим в фоне. Пользователь получает 200‑ку с прошлой версией мгновенно, фон обновляет кэш, следующий запрос придёт уже к свежему. Описание в RFC 5861, поддерживают практически все современные CDN.
Заголовок ставится со стороны origin или прописывается правилом на edge:
Cache-Control: public, max-age=300, stale-while-revalidate=600
То есть: «храни 5 минут как свежий, ещё 10 минут — можешь отдавать как устаревший, пока обновляешь».
Сценарий 1: главная страница новостного сайта — идеально
Главная новостного — это пример, где SWR работает без оговорок. Контент меняется раз в несколько минут, точная синхронизация не нужна (пользователю всё равно — он увидит новость на 30 секунд позже). Зато трафик предсказуемо большой, и каждое обновление кэша в часы пик — это удар по origin.
Реальный кейс одного нашего клиента: на главной — 9 разных блоков с рекомендациями. Каждый блок ходил к отдельному микросервису. На пиках в момент инвалидации origin получал «шторм» в 1.5 тысячи RPS на пустом кэше. С max-age=120, stale-while-revalidate=300 origin теперь получает один запрос в две минуты от каждого edge‑узла (всего 32 запроса). Остальные — горячий кэш, в том числе устаревший.
Сценарий 2: цена в карточке товара — почти стрельба в ногу
Цена меняется по нескольким триггерам: акции, изменения у поставщика, динамическое ценообразование. Если использовать SWR на саму карточку — пользователь может увидеть старую цену, добавить товар в корзину, и в чекауте удивиться. Юридически — это публичная оферта.
Правильное решение: разделить рендер. Карточка кэшируется как статика (заголовок, описание, фото), а блок цены подгружается отдельным fetch‑запросом без SWR, с очень коротким TTL — 5–10 секунд. Тогда мгновенное TTFB остаётся, а критичные данные всегда свежие.
Эмпирическое правило: всё, что попадает в чекаут, корзину или контракт — без SWR. Всё, что является публичным контентом — с SWR.
Сценарий 3: API внутреннего dashboard — спорно
Дашборды аналитики — частый случай, где SWR кажется удобным: пользователь хочет, чтобы графики прогружались мгновенно, а небольшая задержка обновления допустима. Но есть нюанс: на дашбордах пользователи часто кликают «обновить» и ждут именно свежих чисел. SWR в этой ситуации ломает ментальную модель — «я нажал, но числа те же».
Что делаем мы:
- SWR включаем только на «фоновых» виджетах (топ‑10 страниц за неделю, тренды)
- Виджеты, где пользователь ожидает свежести (текущий RPS, последние ошибки), — без SWR, с TTL 5 секунд
- Кнопка «Обновить» обходит кэш через
?nocache=1с отдельным rate‑limit
Чек‑лист перед включением SWR
- Ресурс — публичный? Не зависит от пользователя?
- Если данные устарели на 30 секунд / 1 минуту / 5 минут — пользователь это заметит и пострадает?
- Есть ли альтернатива в виде разделения рендера на «статичную часть» и «динамическую»?
- Понимает ли команда, что инвалидация не делает кэш мгновенно свежим — только запускает фоновую перевыдачу?
- Есть ли мониторинг «возраста» ответа в логах CDN, чтобы детектить аномальный stale?
Если на все ответили «да» — включайте. SWR один из тех инструментов, которые экономят инфраструктуру на порядок. Только не на цене товара.