Когда страницы сайта отдаются из кэша nginx, WordPress видит не каждого посетителя, а только первого. Остальные получают готовый HTML, собранный когда-то для кого-то другого. Отсюда главный вопрос всего цикла: что можно печатать в разметку, а что нельзя.

Это первая часть цикла «WordPress на кэшируемом сайте». Цикл о том, как делать комментарии, формы, подписку, счётчики и рекламу, чтобы они не ломали кэш, а кэш не ломал их. Как устроен и прогревается сам кэш — в циклах «Кэш страниц без MISS» и «Кэш фрагментов и Redis».

Правило: HTML один на всех

Страница в кэше живёт у нас неделю. Значит, в её разметке может быть только то, что одинаково для всех посетителей и не меняется чаще, чем сбрасывается кэш.

Можно в HTMLНельзя в HTML
текст статьи, заголовки, картинкитокен формы (wp_create_nonce) — живёт сутки
меню, подвал, контакты из настроекимя посетителя, «вы вошли как…»
пустую формусчётчик просмотров и лайков
кнопку «подписаться»«вы уже подписаны»
место под комментариисписок комментариев, если их модерируют
код рекламного местато, что зависит от куки посетителя

Всё из правой колонки, оказавшись в разметке, будет показано всем посетителям недели в том виде, в каком его увидел первый.

Три пути для того, что меняется

  • В ключ кэша. Если вариантов немного и они известны заранее — язык, мобильная и десктопная версия. Каждый вариант — своя ячейка. Подходит редко: любая кука в ключе умножает число ячеек (подробно — шестая часть цикла про кэш страниц).
  • В обход кэша. Если запрос по смыслу личный: админка, вход, отправка формы. Обход — это полный рендер WordPress на каждый запрос, поэтому список должен быть коротким.
  • На клиент. Страница приходит из кэша, а личное и часто меняющееся скрипт запрашивает отдельно после загрузки. Это путь по умолчанию.

Почему почти всегда — на клиент. Страница остаётся в кэше и отдаётся за десятки миллисекунд, а отдельный запрос маленький: он не рисует страницу, а отдаёт несколько чисел или кусок списка. И его можно сделать после отрисовки, чтобы он не мешал первому экрану.

Что у нас идёт мимо кэша

Вот весь список исключений на этом сайте — его стоит держать коротким и знать наизусть:

map $request_uri $skip_cache_uri {
    default 0;
    "~*/wp-admin/"    1;   # админка и admin-ajax.php
    "~*/wp-login.php" 1;
    "~*/wp-cron.php"  1;
    "~*/xmlrpc.php"   1;
    "~*[?&]s="        1;   # поиск: запросов бесконечно много
    "~*^/wp-json/"    1;   # REST
}
map $http_cookie $skip_cache_cookie {
    default 0;
    "~*comment_author_"      1;
    "~*wordpress_logged_in_" 1;
    "~*wp_postpass_"         1;
}
# плюс любой POST, PUT, DELETE, PATCH

Три куки — служебные куки WordPress: вошедший пользователь, пароль на записи, автор комментария. Прикладных кук (сравнение, избранное, регион) в этом списке быть не должно: кука, попавшая в обход, выключает кэш именно самым активным посетителям (восьмая часть про кэш страниц).

Вторая половина: изменения, которые видят все

Клиентские запросы решают личное. Но есть и общее, что меняется: статья, настройки сайта, код рекламы. Здесь правило обратное: изменение само должно сбросить кэш тех страниц, где его видно, и сразу их прогреть. Как это устроено — в цикле про кэш страниц; в этом цикле — где WordPress меняет данные так, что сброс легко пропустить.

О чём цикл

  • основа: крон, правки мимо save_post, вошедшие пользователи;
  • просмотры и лайки;
  • комментарии: безопасность, кука комментатора, загрузка отдельным запросом;
  • формы: без nonce, запись до отправки, две ошибки, из-за которых заявка не уходит, согласие;
  • подписка по почте и через Telegram-бота;
  • новые ajax- и REST-адреса как дверь наружу, реклама в кэшируемой странице;
  • чек-лист в конце.

Нужен быстрый сайт, на котором при этом работают формы и комментарии?

Пришлите адрес — посмотрю, что у вас лежит в кэшированной разметке и что оттуда стоит убрать.

· полезно?
АЧ
Алексей Чикун веб-разработчик, команда TRIOHEAD

Делаю сайты и сервисы целиком: от вёрстки до сервера. Пишу о том, что проверил на своих проектах.

Комментарии

// загружаю комментарии…

Комментарии публикуются после проверки. Ссылки и HTML не принимаются.