Після запуску сайту багато хто виявляє, що кожен другий запит до сервера — повний. На мобільних пристроях LCP перевищує 4 секунди. Типовий сайт з 1000 відвідувачів на день генерує близько 10 000 запитів, з яких 60% можна кешувати. Причина — відсутність або неправильне налаштування HTTP-кешування. Наші інженери налаштовують Cache-Control та ETag, щоб статика віддавалася з браузера миттєво, а динаміка перевірялася без повторної передачі тіла. Правильне кешування скорочує кількість запитів на 80% і зменшує LCP на 500–700 мс, безпосередньо впливаючи на Core Web Vitals. На одному з проектів налаштування immutable та stale-while-revalidate знизило навантаження на сервер на 60% і покращило INP на 150 мс.
Як Cache-Control впливає на Core Web Vitals?
Core Web Vitals (LCP, CLS, INP) залежать від кількості запитів і часу відповіді сервера. Ресурси з max-age=31536000 не запитуються з сервера рік, що критично для мобільних користувачів з повільним інтернетом. Порівняння: директива immutable виключає умовні запити при оновленні сторінки, тоді як без неї браузер робить перевірки If-Modified-Since або If-None-Match. Завдяки immutable ці перевірки скорочуються на 100%, економлячи до 200 мс на кожному ресурсі при перезавантаженні. Використання ETag замість Last-Modified дає виграш у трафіку до 5 разів для динамічних відповідей.
Які директиви Cache-Control використовувати?
| Директива | Значення |
|---|---|
| public | Кешувати в браузері та на проксі/CDN |
| private | Тільки в браузері (не на CDN) |
| no-cache | Завжди перевіряти актуальність через сервер |
| no-store | Ніколи не кешувати |
| max-age=N | Кешувати N секунд |
| s-maxage=N | Для CDN (перевизначає max-age) |
| immutable | Файл не зміниться — не перевіряти навіть при F5 |
| must-revalidate | Після max-age — обов'язково перевірити |
Часті помилки — забувають immutable для статики, не ставлять Vary: Accept-Encoding, або для API використовують public. Без Vary близько 2-3% користувачів можуть отримати нечитабельний контент, якщо CDN віддасть gzip-версію без підтримки gzip.
Порівняння стратегій кешування для різних типів контенту
| Тип контенту | Приклад директив | Причина |
|---|---|---|
| JS/CSS (з хешем) | public, max-age=31536000, immutable |
Файл не змінюється — можна кешувати назавжди |
| HTML | public, max-age=300, must-revalidate |
Часто оновлюється, але свіжість не критична |
| API | no-cache, no-store |
Дані змінюються динамічно |
| Зображення | public, max-age=2592000 |
Довгий кеш без immutable — можуть бути перезалиті |
Коли використовувати ETag замість Last-Modified?
ETag — унікальний ідентифікатор версії ресурсу, що генерується на основі хешу вмісту. Last-Modified використовує лише дату, що менш точно. Якщо файл змінився, але дата залишилася (баг сервера), Last-Modified не спрацює. ETag обов'язковий для динамічних сторінок: сервер перевіряє заголовок If-None-Match і повертає 304 Not Modified, економлячи до 100% розміру відповіді. В nginx ETag включений за замовчуванням (etag on;). На одному проекті ми замінили Last-Modified на ETag і знизили трафік API на 40%.
Як налаштувати заголовки для статики та API?
Приклад конфігурації Nginx
# Nginx конфігурація для всіх типів ресурсів # Статичні активи з хешем (Vite, Webpack) location ~* \.(js|css)$ { expires 1y; add_header Cache-Control "public, max-age=31536000, immutable"; add_header Vary Accept-Encoding; } # Шрифти — теж immutable location ~* \.(woff2|woff|ttf|eot)$ { expires 1y; add_header Cache-Control "public, max-age=31536000, immutable"; add_header Access-Control-Allow-Origin *; } # Зображення — довгий кеш без immutable location ~* \.(webp|avif|jpg|jpeg|png|gif|svg|ico)$ { expires 30d; add_header Cache-Control "public, max-age=2592000"; } # HTML — короткий кеш з must-revalidate location ~* \.html$ { expires 5m; add_header Cache-Control "public, max-age=300, must-revalidate"; } # API — не кешувати location /api/ { add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma no-cache; } Продвинуті техніки: Stale-While-Revalidate та Vary
Директива stale-while-revalidate дозволяє віддавати застарілий кеш миттєво, а в фоні оновлювати його. Приклад: Cache-Control: public, max-age=300, stale-while-revalidate=3600 — користувач отримує дані за 0 мс, свіжа версія підвантажується асинхронно до наступного візиту. Це покращує сприйняття швидкості — жодних затримок. Без stale-while-revalidate довелося б або ставити короткий max-age (часті запити) або довгий (ризик застарілих даних). Порівняно з простим max-age без ревалідації, ця директива скорочує час очікування для користувача на 100% при наявності застарілого кешу.
Заголовок Vary гарантує, що CDN врахує кодування стиснення. Без нього близько 2-3% користувачів можуть отримати нечитабельний контент, якщо CDN віддасть gzip-версію браузеру без підтримки gzip. Як зазначено в документації, це вирішує проблему повністю.
Процес налаштування під ключ
- Аудит — аналізуємо поточні заголовки, виявляємо проблемні ресурси (за допомогою Chrome DevTools, Lighthouse).
- Проектування — визначаємо стратегію для статики, HTML, API, зображень, шрифтів.
- Налаштування Nginx/Apache — застосовуємо директиви з урахуванням CDN.
- Впровадження ETag — для API та динаміки генеруємо хеші на основі дати зміни даних.
- Конфігурація CDN — встановлюємо
s-maxage,Vary, правила інвалідації. - Тестування — перевіряємо через curl та інструменти (GTmetrix, WebPageTest).
- Документація — фіксуємо схему кешування та інструкцію з інвалідації.
Що ви отримаєте
- Скорочення кількості запитів на 80%.
- Покращення LCP на 500–700 мс.
- Зниження навантаження на сервер до 60%.
- Економію на CDN-трафіку до 70%.
- Детальний звіт з аудитом та рекомендаціями.
- Конфігурації Nginx/Apache для вашого стеку.
- Документацію з інвалідації кешу для розробників.
- Консультацію щодо подальшої оптимізації.
Зв'яжіться для консультації — ми покажемо, яких покращень можна досягти на вашому сайті. Досвід команди — 7 років, понад 50 проектів з налаштованим кешуванням. Замовте аудит кешування сьогодні та отримайте детальний звіт з рекомендаціями.







