HTTP-заголовки кешування (Cache-Control) 🚀 — детальний огляд

Уявіть, що ви щоранку приходите в одну й ту ж кав’ярню і питаєте баристу: “Які кави ви варите?”. Він перелічує все меню. Наступного ранку ви знову питаєте те саме, і він знову перелічує. Це марнування часу, правда? Логічніше було б запам’ятати той невеличкий перелік доступної кави і питати про нього лише тоді, коли він зміниться.

Саме так працює кешування в браузері. Без нього ваш браузер при кожному відвідуванні сторінки змушений заново завантажувати кожну картинку, скрипт і стиль. Це повільно і дорого. HTTP-заголовки кешування — це інструкції, які сервер дає браузеру: “Запам’ятай цей файл на тиждень” або “Перевіряй цей файл при кожному візиті”.

У цій статті я розповім про те, як правильно налаштувати ці інструкції, щоб ваш сайт літав, а сервер не “задихався” від зайвих запитів.

 

Головний гравець: Cache-Control

Раніше для кешування використовували заголовок Expires, але сьогодні стандартом де-факто є Cache-Control. Це потужний інструмент, який дозволяє дуже гнучко керувати поведінкою кешу.

Він складається з директив. Давайте розберемо найважливіші з них:

Директива Що вона означає
max-age=3600 Файл вважається “свіжим” протягом вказаної кількості секунд (тут — 1 година). Браузер навіть не буде питати сервер про цей файл, поки час не спливе.
public Файл може кешуватися будь-ким: браузером, CDN, проксі-сервером. Ідеально для статики.
private Файл призначений для одного користувача (наприклад, сторінка профілю). Кешувати може тільки браузер, але не CDN.
no-cache Увага, пастка! Це не означає “не кешувати”. Це означає “кешуй, але перед кожним використанням питай сервер, чи файл не змінився” (валідація).
no-store Ось це справді “не кешувати ніде і ніколи”. Використовується для банківських даних та конфіденційної інформації.
must-revalidate Коли термін max-age спливе, браузер зобов’язаний перевірити актуальність файлу на сервері, а не використовувати стару копію.

 

Як браузер дізнається, що файл змінився? (Валідатори)

Коли ви використовуєте no-cache або коли спливає час max-age, браузер робить запит до сервера: “У мене є картинка, ось її мітка. Вона все ще актуальна?”. Для цього існують два заголовки-валідатори:

  • ETag (Entity Tag): Унікальний хеш-код файлу (наприклад, "33a64df551425fcc55e4d42a148795d9f25f89d4"). Якщо хеш на сервері збігається з тим, що є у браузера, сервер відповідає 304 Not Modified (тіло файлу не передається).
  • Last-Modified: Дата останньої зміни файлу. Менш точний, ніж ETag, але теж популярний.

 

Практика: як налаштувати кешування

Налаштування залежить від того, який веб-сервер ви використовуєте. Якщо ви не впевнені, раджу прочитати мою статтю про різницю між Nginx та Apache.

 

Варіант 1: Nginx (Найефективніший)

Додайте цей код у блок server вашого конфігураційного файлу:

# Кешування статики (зображення, шрифти) на 1 рік
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
    expires 365d;
    add_header Cache-Control "public, no-transform";
}
# Кешування HTML (не кешуємо або кешуємо з перевіркою)
location ~* \.(html)$ {
    add_header Cache-Control "no-cache";
}

 

Варіант 2: Apache (.htaccess)

Якщо ви використовуєте Apache, додайте цей код у файл .htaccess у корені сайту. Вам знадобиться модуль mod_expires.

<IfModule mod_expires.c>
    ExpiresActive On    
    # Зображення
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"    
    # CSS та JS
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"    
    # За замовчуванням
    ExpiresDefault "access plus 2 days"
</IfModule>
# Додатковий контроль заголовків
<IfModule mod_headers.c>
    <FilesMatch "\.(js|css|xml|gz|html)$">
        Header append Vary: Accept-Encoding
    </FilesMatch>
</IfModule>

 

Варіант 3: PHP (Для динамічного контенту)

Іноді потрібно заборонити кешування конкретної динамічної сторінки (наприклад, кошика). Це можна зробити прямо в коді:

<?php
// Забороняємо кешування
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>

 

Поширені помилки ⚠️

  1. Кешування файлів, що часто змінюються, без версіонування. Якщо ви поставите max-age=1 рік на style.css і зміните дизайн, користувачі будуть бачити старий дизайн ще рік. Рішення: змінюйте ім’я файлу при оновленні (наприклад, style.v2.css або style.css?v=2).
  2. Використання public для приватних даних. Ніколи не використовуйте public для сторінок, де є особисті дані користувача, інакше вони можуть залишитися в кеші публічного проксі.
  3. Відсутність заголовків. Якщо ви не надішлете жодних заголовків, браузер сам спробує “вгадати”, як кешувати контент (Heuristic Caching), і результат може бути непередбачуваним.

 

Висновок: баланс між швидкістю та актуальністю

На мою думку, налаштування заголовків кешування — це мистецтво знайти баланс. Ви хочете, щоб користувач завантажував якнайменше даних (довгий кеш), але при цьому завжди бачив актуальну версію сайту.

Мій рецепт простий: “агресивно” кешуйте статику (картинки, шрифти) з довгим терміном життя, використовуйте версіонування файлів для CSS/JS, і будьте обережні з кешуванням HTML-сторінок, використовуючи no-cache для динамічного контенту.

 

Recent Posts

Наомі Кемпбелл

Дуже багато людей недооцінюють те, що у них є, і переоцінюють те, чого у них…

6 днів ago

Волтер Дісней

Якщо ви можете це уявити, - ви можете це зробити Волтер Дісней  

1 тиждень ago

Теодор Рузвельт

Варто тільки повірити, що ви можете – і ви вже на півдорозі до цілі Теодор…

1 тиждень ago

Надійна інфраструктура для бізнесу: VPS і виділені сервери в Україні

Успішний бізнес у 2025 році неможливо уявити без стабільної ІТ-інфраструктури. Від корпоративного сайту до CRM-системи…

2 тижні ago

WordPress як Headless CMS 🧠 | практично з REST API

WordPress роками був неперевершеним "монолітом": він відповідав і за зручну адмін-панель, і за збереження даних,…

4 тижні ago

Тандем Nginx + Apache 🤝 Як поєднати швидкість та гнучкість

У світі веб-серверів часто говорять про протистояння Nginx vs Apache. Але що, якби я сказав…

4 тижні ago