Уявімо, що на сайті бібліотеки змінили сьогоднішні години роботи, але частина відвідувачів досі бачить старий час. Спершу треба розрізнити причини: оригінал на сервері не оновився, браузер повторно використав збережену відповідь або проміжний сервер надав попередню версію. Сам факт багаторазового оновлення сторінки не показує, на якому етапі виникла проблема.
HTTP-кеш зберігає отримані відповіді та використовує їх знову за відповідних умов. У статті вигаданий загальнодоступний розклад пов’язує вказівки Cache-Control щодо зберігання й перевірки з ETag і відповідями 304. Наведені обміни скорочені для пояснення, а не отримані під час вимірювань справжньої бібліотеки чи конкретного сервера. Мета — пояснити, яку відповідь і коли можна використати знову, а не запропонувати видалити всі кеші.
1. Чи зберігати, чи перевіряти та з ким ділитися
Читаючи політику кешування, окремо запишіть три запитання: чи можна зберегти відповідь, чи можна відразу використати копію для наступного запиту та чи можна ділитися нею між користувачами? Дозвіл на зберігання не означає необмеженого повторного використання, а перевірка актуальності не дозволяє ділитися з іншими. Стандарт HTTP-кешування RFC 9111 задає ці умови різними директивами. Нижче розглянуто директиви відповіді без додаткових аргументів з іменами полів.
| Запитання для рішення | Директива відповіді | Значення, яке треба розрізнити |
|---|---|---|
| Чи заборонено зберігати відповідь? | no-store | Вказівка не зберігати її для подальшого використання |
| Чи потрібна перевірка перед повторним використанням? | no-cache | Зберігати можна, але повторне використання потребує успішної перевірки |
| Чи можна ділитися між користувачами? | private | Забороняє зберігання в спільному кеші, але не забороняє його цілком у приватному |
Наприклад, якщо публічний розклад часто змінюється за тією самою адресою, можна розглянути вимогу перевіряти його перед використанням навіть за наявності копії. Персоналізовані екрани відрізняються від публічного розкладу вже умовами спільного використання. private стосується спільного кешу й не замінює вхід та перевірку повноважень. Звівши різні цілі до одного налаштування, під час прискорення можна неправильно визначити адресата інформації.
У таблиці політики фіксуйте не лише директиву, а й причину: чи є розклад публічною інформацією, зміни якої треба перевіряти, чи незмінний вміст логотипа та чи надходить за тією самою адресою особиста інформація. Це початок класифікації справжніх відповідей, а не готове налаштування для всіх сайтів. Також розрізняйте сховища, до яких воно застосовується, наприклад браузер і CDN.
2. Не вибирати no-cache і no-store лише за назвою
Назву no-cache легко сприйняти як заборону зберігання, однак у відповіді вона вимагає перевірити копію перед її повторним використанням. Якщо сервер підтвердить відсутність змін, збережене тіло можна використати ще раз. no-store натомість указує не зберігати цю відповідь. Оскільки відрізняються і дані для зберігання, і перевірка в наступному запиті, однакової поведінки двох налаштувань очікувати не слід.
Стан fresh у кеші означає, що політика дозволяє повторне використання без додаткової перевірки. Він не гарантує, що власник за цей час не змінював вміст. Якщо строк використання задано через max-age, раніше збережена відповідь може обиратися і після зміни оригіналу в межах цього строку. Спочатку визначте допустиму затримку оновлення, а потім пов’яжіть вимогу з директивою. Не копіюйте довільний тривалий строк зберігання як універсальне рішення для швидкодії.
Посібник MDN з HTTP-кешування пояснює, що додавання no-store до нової відповіді не видаляє стару відповідь, уже збережену для цього URL. Якщо попередня копія ще придатна й нової відповіді не запитують, новий заголовок теж може не надійти. Не вважайте no-store командою очищення всіх кешів або достатньою умовою приватності; перевірте строк життя наявних відповідей та оновлення керованих кешів.
3. Простежити повторний візит через ETag і 304
Нехай вигадана адреса розкладу /hours.json спочатку повідомляє про закриття о 18:00. Нижче наведено пояснювальний формат HTTP/1.1 лише з потрібними частинами; інші заголовки справжньої відповіді опущено. hours-v1 — визначений сервером ідентифікатор представлення в цьому прикладі, а не формула обчислення часу чи справжній хеш файла.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache
ETag: "hours-v1"
{"closes":"18:00"}
Якщо браузер зберіг відповідь, наступного разу він може передати ETag у заголовку If-None-Match умовного запиту. Коли сервер визначає, що умова відповідає обраному поточному представленню та змін немає, він повертає 304 Not Modified. Наступний блок — скорочений запис запиту та відповіді один за одним. Він не показує повторного надсилання JSON розкладу після 304.
GET /hours.json HTTP/1.1
Host: library.example
If-None-Match: "hours-v1"
HTTP/1.1 304 Not Modified
Cache-Control: no-cache
ETag: "hours-v1"
Як пояснює документація MDN щодо ETag, клієнт тоді використовує збережене тіло. У відповіді 304 нового тіла немає, але запит і перевірка однаково потребують обміну даними. Якщо закриття перенесли на 19:00 і представлення сервера теж змінилося, на стару умову можна очікувати відповідь 200 із новим тілом та ідентифікатором. no-cache не гарантує постійної відповіді 304 та не усуває сам собою запити до бази даних.
Перевіряти варто не один код стану, а відповідність вмісту та ідентифікатора. Якщо вміст змінився, але сервер зберіг старий ETag, результат перевірки може бути неправильним. Якщо ж за незмінного вмісту ідентифікатор постійно змінюється, тіло може надсилатися частіше. Потрібно перевірити на сервері зв’язок способу генерування з обраним представленням; сама наявність ETag не доводить правильності реалізації.
4. Відрізняти змінюваний документ від ресурсу з новою назвою
Документ на зразок розкладу, вміст якого змінюється за тим самим URL, та логотипи або скрипти, що отримують нові назви за зміни вмісту, можуть потребувати різних стратегій. Якщо logo.a1.png замінено на logo.b2.png, новий документ має посилатися на нову адресу. Додавши ідентифікатор до назви, але потім перезаписавши старий файл, ви порушуєте принцип спільного керування адресою і вмістом.
Саме завантаження нового файла не змушує відвідувача запитати нову адресу. Якщо отриманий HTML досі посилається на старий логотип, попередній ресурс може використовуватися знову. Тож перевіряйте не лише кешування ресурсу, а й шлях оновлення документа, який на нього посилається. Замість однакового строку зберігання для обох поясніть, якою може бути затримка оновлення кожного.
Під час розгортання старі й нові документи деякий час можуть використовуватися разом. Публікація документа до готовності нового ресурсу або надто раннє видалення старого створюють окремі збої. У цьому вигаданому прикладі можна перевіряти наявність файлів нового документа та доступність файлів старого. Зміна назви — інструмент проєктування кешу, а не автоматичне розв’язання всіх питань послідовності розгортання і відкату.
5. Перевіряти по одній гіпотезі в панелі Network
Безпосередню перевірку почніть із базового запису за дозволеного кешу. Разом перегляньте точний URL і рядок запиту, версію розкладу на екрані, стан відповіді, If-None-Match запиту та Cache-Control і ETag відповіді. Навіть однойменні заголовки запиту та відповіді задають умови різних сторін; запишіть, який саме читаєте. Документація Chrome DevTools Network пояснює, як розрізняти ці дані в Headers.
| Вигадана ситуація перевірки | Записи для зіставлення | Якого поспішного висновку не можна робити |
|---|---|---|
| Повторно запитати той самий розклад | Умовний запит, стан, час на екрані | 304 означає повну відсутність обміну даними |
| Змінити вихідний час і зробити запит | Нове тіло, ETag, справжній URL | Позначка успішного збереження означає оновлення для всіх |
| Зробити запит із вимкненим кешем браузера | Відмінність першого завантаження від повторного візиту | Це звичайна швидкість повторного відвідування |
| Повернутися кнопкою «Назад» | Наявність нового запиту та відновлений екран | Поява екрана обов’язково означає нову HTTP-перевірку |
Далі окремо випробуйте вимкнення браузерного кешу. У Chrome параметр Disable cache діє, поки відкрито DevTools, тому фіксуйте і стан інструмента, і значення параметра. Це корисно для вивчення першого завантаження, проте не тотожне перевірці використання копії за звичайного повторного візиту. Не зафіксувавши налаштування, можна помилково визнати кеш несправним через постійне отримання нових даних. Зберігайте умови досліду, щоб повернутися до дозволеного кешу й порівняти.
Причину легше звузити, якщо не робити кілька змін і багато запитів одночасно. Спочатку перевірте повторний візит без змін вмісту, потім змініть один час і простежте відповідь. Одночасна зміна URL документа, параметрів сервера та назви файла не дає легко визначити причину результату. Якщо очікуваних 200 або 304 немає, перед додаванням нових налаштувань перечитайте фактичні запит і відповідь.
6. Перевіряти інші шляхи зберігання та критерії завершення
Не припускайте, що вимкнення HTTP-кешу браузера прибирає CDN перед сервером або інші сховища застосунку. Окремо можна перевірити, чи обробляє запит service worker, яку відповідь обирає проміжний сервер і чи не тримає застосунок на екрані раніше отримані дані. Однаковий URL не означає, що всі шари використовують ту саму копію.
Повернення кнопкою «Назад» теж відрізняйте від нового HTTP-запиту. Коли браузер відновлює екран попереднього сеансу, очікуваний запит перевірки може не з’явитися навіть за no-cache. Якщо одразу вважати це доказом ігнорування заголовка сервером, причина може бути визначена неправильно. Окремий запис справжніх запитів за нової навігації, оновлення та повернення допомагає не об’єднувати різні явища в одну проблему.
Критерій завершення для розкладу — не лише частка влучань у кеш. Перевірте правильне використання копії без змін, появу нової інформації в допустимий строк після зміни та правильне коло користувачів спільної відповіді. Записи часу зміни й спостереження, умов і фактичного тіла допоможуть іншим відтворити ситуацію. Якщо швидкість покращилася, але неправильні години довго залишаються на екрані, вихідну вимогу не виконано.
У робочому середовищі розглядайте політику кожного типу відповіді разом із процесами оновлення та відкату. Не копіюйте правила публічного документа на персоналізовану відповідь і не прирівнюйте успішну перевірку до перевірених прав доступу. Заголовки передають правила зберігання та повторного використання. Пояснення того, що було збережено та через які перевірки дійшло до поточного екрана, дозволяє точніше діагностувати застарілу сторінку.