Как браузер и сервер кэшируют запросы и не возникает ли дублирования кэширования
Что проверяют
Понимаете ли вы, что кэшей на пути запроса несколько: браузер, Service Worker, CDN, обратный прокси, кэш приложения на сервере. Вопрос про «дублирование» на деле о том, как этими слоями управлять и сколько устаревших данных они могут накопить. Следом обычно спрашивают, как выкатить новую версию фронтенда, чтобы пользователи её увидели.
Как отвечать
Копии в разных слоях это норма: каждая экономит свой отрезок пути. Проблема не в дублировании, а в согласованности, и управляют ей заголовки ответа:
Cache-Control: max-age: сколько секунд ответ свежий, всё это время браузер не ходит в сеть;s-maxage: срок для общих кэшей (CDN, прокси), браузер его игнорирует;private: хранить может только браузер, для персональных ответов обязательно;no-cache: хранить можно, но перед использованием перепроверять. Хранение целиком запрещаетno-store;ETagиLast-Modified: условные запросы сIf-None-MatchиIf-Modified-Since, сервер отвечает304без тела;stale-while-revalidate: отдать устаревшее сразу и обновить в фоне;Vary: по каким заголовкам запроса хранить разные версии.
Стандартная схема для SPA: файлы сборки с хэшем в имени отдаются с max-age=31536000, immutable, а index.html с no-cache. Новый деплой меняет имена файлов, и браузер забирает их сам.
Отдельный слой на клиенте это кэш данных TanStack Query, SWR или Apollo. Вот здесь дублирование реально мешает: если API отдаёт max-age=300, принудительный рефетч в библиотеке получит тот же старый ответ из HTTP-кэша браузера.
Где спотыкаются
Считают, что no-cache запрещает кэширование. Это делает no-store.
Кэшируют персональные ответы в CDN без private, и один пользователь получает страницу другого.
Уверены, что очистка CDN сразу обновит всех. Браузеры держат копию до истечения своего max-age, поэтому худший срок устаревания складывается из сроков всех слоёв.