nginx не сохраняет в кэш ответ, в котором есть заголовок Set-Cookie. Это правильно: иначе кука первого посетителя уехала бы всем. Но у этого правила есть следствие, о котором вспоминают поздно: если шаблон ставит куку при каждом рендере, страница не попадёт в кэш никогда.
Это седьмая часть цикла «Кэш страниц без MISS».
Почему не помогает даже прогрев
Обходчик приходит без кук — значит, шаблон ставит куку и ему. Ответ с Set-Cookie не сохраняется. Обход честно проходит все страницы, отчёт зелёный, а в кэше пусто. Каждый посетитель получает полный рендер.
Как это выглядело
На одном сайте из 89 страниц в кэше держались только 25. Виновников оказалось два:
- счётчик просмотров писал куку «уже смотрел эту запись» прямо в шаблоне записи;
- дубль метки рекламного источника ставил куку даже на прямых заходах, без всякой рекламы.
После лечения — 89 из 89 и 22 из 22 на втором сайте той же темы, ни одного Set-Cookie в ответах страниц.
Как лечили
- Счётчик просмотров — отдельным ajax-запросом после загрузки страницы. HTML не меняется, кука ставится в ответе на этот запрос, а он не кэшируется и не должен.
- Метку источника — только когда в адресе действительно есть рекламный параметр. Что делать с самим рекламным трафиком — в одиннадцатой части.
Проверка за минуту
# кто ставит куки в коде (имя куки бывает в константе — ищем вызов, а не имя)
grep -rn "setcookie" wp-content/themes/ wp-content/plugins/ --include=*.php
# что отдаёт страница без кук
curl -s -o /dev/null -D - https://сайт/страница/ | grep -iE 'set-cookie|x-cache-status'
Ищите вызов, а не имя куки. Имя часто лежит в константе или собирается из строки — поиск по имени ничего не найдёт.
Кэш включён, а страницы всё равно медленные?
Пришлите адрес — проверю, не ставит ли сайт куку на каждом рендере.
// загружаю комментарии…