Как заставить браузер/CDN загрузить обновлённый файл, а не взять старый из кэша (cache busting)?

Проблема
Браузер или CDN может хранить статические файлы (JS/CSS/изображения) долго по кэшу. Если развернули новую версию файла под тем же URL, клиенты увидят старую версию — баги, несоответствие кода/стилей.
 
🎯 Зачем спрашивают
  • Проверить, понимает ли кандидат как работает кэширование браузера и CDN, и почему это влияет на доставку фронтенда.
  • Убедиться, что он умеет балансировать перформанс vs обновляемость (ведь кэш = ускорение, но обновления должны доходить до клиента).
  • Посмотреть, знает ли кандидат практики продакшен-разработки (fingerprinting, заголовки, invalidate через CDN API).
 
📝 Ответ
Коротко: Изменять URL ресурса при каждом изменении контента. Тогда кеш «сломается» (cache-busted) автоматически — браузер/CDN считает это новым ресурсом.
 
Способы решения:
Fingerprinting / Content hashing
Включать в имя файла хэш, рассчитанный по содержимому: app.[contenthash].jsapp.3f4a1b.js. При изменении содержимого хэш меняется → новый URL → новый запрос.
Обычно реализуется в сборщиках: Webpack, Rollup, Parcel, Vite, и другие.
 
Позволяет ставить Cache-Control: max-age=31536000, immutable (долго-кэшируемые), т.к. при обновлении будет новый файл.
Query string versioning
Добавлять версию в запрос: app.js?v=20250928 или app.js?v=3f4a1b.
 
⚠️
Некоторые CDN/прокси по умолчанию игнорируют query-параметры при кэшировании или кэшируют не так.
Простая реализация при отсутствии сборщика или если нужно решить проблему в моменте.
Инвалидация кэша на стороне CDN
Если по каким-то причинам нужно форсировать обновление старого URL, вызывают API CDN (purge) для удаления кеша.
Моментная мера. Обычно за таким обращаются к поддержке инфраструктуры.
 
⚖️ Компромиссы
  • Hashing: максимально надёжно, но требует пайплайна сборки/деплоя.
  • Query string: просто, но нестабильно → некоторые CDN игнорят.
  • CDN purge: быстро, но дорого (иногда платно) и не всегда мгновенно.
 
🔎 Встречные вопросы
  • Почему app.js?v=hash хуже, чем app.hash.js?
  • Как обновлять Service Worker, чтобы не застрять на старом кэше?
  • Как работает immutable в Cache-Control и почему это важно?
 
🚩 Красные флаги
  • Просто отключим кэш через Cache-Control: no-store (удар по перформансу).
  • Всегда можно сходить и почистить кэш руками
  • CDN сам обновляет файлы при деплое (не всегда).
 
🛠 Практика
 
📚 Источники / ссылки