Перейти к содержанию
Tverknit

Обновление кеша пререндеринга

Страницы с пререндерингом грузятся молниеносно. Но есть подвох: они не обновляются автоматически. Когда данные меняются в базе, рендеринг страницы остаётся старым — кеш показывает пользователю устаревший контент. На блоге новая статья не видна. В магазине цена обновилась, а кеш показывает старое значение. Обновление кеша пререндеринга — решение, позволяющее использовать оба преимущества: скорость при рендеринге и свежесть контента. В статье разберем стратегии обновления — от простых примеров до решений для приложений под нагрузкой. Главное — баланс между производительностью рендеринга и актуальной информацией для пользователя.

Кеш пререндеринга показывает снимок прошлого: данные в системе обновились, но страница остаётся старой
Кеш пререндеринга показывает снимок прошлого — данные в системе обновились, но страница остаётся старой

Представьте ресторан, который вывесил на стену ламинированное меню. Оно грузится в голове посетителя мгновенно — свежее, быстро. Но повар давно переделал половину блюд, убрал три позиции, добавил новые. Меню на стене не обновилось. Гости заказывают несуществующие блюда, повар их не готовит. Уходят в другой ресторан. Ресторан теряет деньги.

Так работает статический html при изменении данных. Сначала это чудо — готовый html грузится за миллисекунды. Потом это боль, когда данные устаревают. Кеш показывает снимок прошлого.

Почему это больно на практике

Запустили блог. Написали статью в 3 часа ночи. Опубликовали. Проверили главную — статья не видна. Проверили ещё раз через час — всё ещё нет. В базе данных она живёт, прямой поиск находит. Но главная показывает вчерашний список.

Статья не получает трафик. Тысячи потенциальных читателей видят только старые посты. Это происходит потому, что готовый html главной не обновляется самостоятельно. Никакой процесс рендеринга не запустился. Кеш просто лежит с устаревшей информацией, пока вы не вызовете обновление контента вручную.

Где это переходит в убытки: три реальных сценария

Интернет-магазин. Цена товара упала с 5000 рублей до 3000. В базе данных стоит 3000. Кеш показывает 5000. Покупатель видит высокую цену, уходит к конкуренту. Умножьте это на тысячи посетителей в день — конверсия падает на 2-3%. За неделю можно потерять миллионы рублей, потому что кеш не обновляется автоматически.

Каталог товаров. Товар раскупился. В БД статус «недоступен». Кеш всё ещё показывает «в наличии». Покупатели заказывают несуществующие вещи. Вы часами отменяете заказы, делаете возвраты. Система выглядит ненадёжной.

Новостной сайт. Крупная новость в 10 утра. На главной вчерашние новости — потому что статический html не обновлён. Читатели ищут свежее в других источниках. Трафик уходит конкурентам.

Когда приложение получает тысячи запросов в минуту, даже несколько часов без обновления контента могут обойтись в миллионы упущенной выручки.

Нагрузка на сервер при обновлении контента

При обновлении кеша система повторно рендерит страницу и обращается к источникам данных. Если одновременно пересобрать сотни адресов, число запросов определяется количеством страниц и запросов на каждую из них, поэтому нагрузку нужно ограничивать очередью и параллелизмом.

Например, одновременное истечение кеша у 500 статей создаёт залповую нагрузку — cache stampede. Разнесите срок жизни, обновляйте страницы небольшими партиями и не удаляйте предыдущую версию до успешной пересборки.

Edge cases высоконагруженных систем

На высоконагруженных приложениях проблемы обостряются.

Race conditions. При параллельных обновлениях один процесс генерирует кеш на момент времени T, другой на T+100ms. В базе появились новые данные. Они оба записывают результат. Теперь в памяти смешанные данные: часть старая, часть новая. Пользователь видит странный результат.

Несогласованность распределённого кеша. Если Redis на трёх узлах и обновились только два, третий ещё хранит старые данные. Разные пользователи получают разный контент.

Каскадные отказы. Webhook для обновления работает асинхронно. Если очередь запросов зависает, события накапливаются. Потом приходят залпом. Сервер перегружается. Становится медленнее. Webhook обрабатываются ещё медленнее. Система ломается.

Когда обновлять: выбор времени жизни

Универсального ответа нет. Это зависит от типа контента и приложения.

Для статичных страниц (информация о компании) время жизни может быть неделя. Контент меняется редко, нагрузка — минимальная.

Для новостей и каталогов — часы или минуты. Актуальность критична.

Для цен и статуса товаров — минуты или даже секунды. Неправильная цена стоит денег прямо.

Для лент и аналитики — иногда секунды.

Когда вы выбираете время жизни, вы балансируете между тремя факторами: насколько свежий контент нужен пользователю, какую нагрузку может выдержать сервер и как часто нужно обновлять данные. Нет идеального решения — только оптимальное для вашего случая.

Ниже разобраны три базовые стратегии обновления: расписание, webhooks и ISR, даже когда приложение получает миллионы запросов в день.

Стратегии обновления кеша SSG

Как работает рендеринг по расписанию?

Самый простой способ — стратегия запланированной пересборки всего сайта с рендерингом по расписанию. Пример использования: рендеринг блога выполняется автоматически ежедневно в 6 утра. При времени генерации рендеринга в минуты пользователи видят свежий контент. Загрузки страницы остаются стабильны и предсказуемы.

Как обновлять и сбрасывать кеш через webhooks?

Когда контент меняется часто, требуется удалять кеш страницы. Webhooks запускают рендеринг при изменении. Пример: интернет-магазин с ценами обновляется за минуты, значения видны свежие. Этот подход лучше для динамичного контента, нагрузка снижается. Изменения на странице применяются мгновенно.

Как ISR создаёт новые версии через prerender?

Incremental Static Regeneration в Next.js сочетает оба подхода. Каждая страница кешируется, затем обновляется в фоне. Рендеринг не участвует в запросе страницы, как при server-side rendering. Пользователи видят быстрый кеш страницы, изменения применяются. Это оптимальный вариант для приложения.

Наверх