Дві суперечливі вимоги: статичні файли мають кешуватися якомога довше (швидкість, трафік), а після деплою користувачі мають одразу отримати нову версію. Розв'язок - різна політика для HTML і для ресурсів з хешем у назві.
1. Ресурси з хешем у назві (app-3f9a1c.js, app-8b2e.css - так їх називає Vite) - кешувати «назавжди»:
Cache-Control: public, max-age=31536000, immutable
Вміст файлу ніколи не змінюється: нова версія - нова назва. immutable каже браузеру не перевіряти файл навіть при оновленні сторінки.
2. HTML - завжди перевіряти актуальність:
Cache-Control: no-cache
no-cache не означає «не кешувати» - браузер зберігає копію, але перед використанням питає сервер, чи вона актуальна. Не кешувати взагалі - це no-store (для сторінок з персональними даними).
Саме HTML посилається на конкретні хешовані файли: новий HTML після деплою - нові назви ресурсів - браузер їх завантажить.
Перевірка актуальності (ревалідація):
- сервер віддає
ETag: "abc123"чиLast-Modified; - браузер наступного разу питає
If-None-Match: "abc123"; - якщо не змінилося -
304 Not Modifiedбез тіла: економія трафіку, але все одно запит по мережі.
Типові помилки:
- довге кешування файлів без хешу (
/js/app.jsзmax-age=86400) - після деплою користувачі добу бачать старий JavaScript з новим HTML, і все ламається; - старі файли видалено при деплої. Користувач з відкритою вкладкою (або HTML з кешу CDN) просить
app-старийхеш.js, а його вже немає - 404 і зламана сторінка. Хорошою практикою є тримати файли попередньої збірки ще якийсь час. CDN з кешем може приховувати проблему: віддає старий файл зі свого кешу, поки той не витісниться; - динамічні частини (
import()) з тієї ж причини падають у давно відкритих вкладках - потрібна обробка помилки завантаження й пропозиція оновити сторінку; Varyне вказано для відповідей, що залежать від заголовків (Accept-Encoding, мова) - CDN може віддати не той варіант.
Шари кешування: кеш браузера, CDN (Cloudflare), зворотний проксі. Для CDN є окремі директиви: s-maxage (лише для спільних кешів) і stale-while-revalidate (віддати застаріле, поки оновлюється у фоні).
У Laravel + Vite файли з public/build/assets мають хеші - для них вебсервер (Nginx, Caddy) налаштовують з immutable. HTML формує Laravel, і для гостьових сторінок кешування на рівні CDN налаштовується окремо від статики.
Перевірка: вкладка Network у DevTools - колонка Size показує (disk cache)/(memory cache) чи розмір, а заголовки відповіді - реальну політику.