В WooCommerce кэш чаще всего начинает мешать не на главной и не в каталоге, а на страницах, где доставка считается по адресу, складу, весу корзины или выбранному способу. Типичный симптом: пользователь меняет город, индекс или способ доставки, а блоки с тарифами, сроками и итоговой суммой остаются старыми. Если при этом включён page cache на уровне плагина, Nginx, CDN или хостинга, проблема может проявляться только у части посетителей и выглядеть как «плавающий баг».
Ниже — рабочая схема, как точечно отключить кэш только там, где он действительно опасен, и не убить производительность всего магазина.
Когда кэш нужно отключать, а когда достаточно исключить фрагмент
Не каждая страница WooCommerce требует полного отключения кэша. Если меняется только один блок, например расчёт доставки в корзине, часто достаточно оставить кэш страницы и обновлять динамику через AJAX. Но если итог зависит от нескольких параметров сразу — адреса, выбранного склада, способа доставки, купона, веса корзины — безопаснее исключить страницу или набор страниц из page cache.
Сценарии, где page cache обычно мешает
- страница корзины показывает старую стоимость доставки после смены адреса;
- checkout не пересчитывает итог после выбора другого способа доставки;
- в одном регионе видны тарифы другого региона;
- после смены склада или точки выдачи остаётся старый список вариантов доставки;
- CDN отдаёт HTML с уже рассчитанными данными, которые нельзя показывать всем подряд.
Диагностика проблемы: что проверить до правки кода
Сначала нужно понять, где именно живёт кэш. В WooCommerce один и тот же симптом может быть вызван не только плагином кэширования, но и серверным кэшем, CDN или даже кеширующим модулем темы.
- Откройте проблемную страницу в режиме инкогнито и сравните поведение с обычным браузером.
- Проверьте заголовки ответа в DevTools: ищите признаки page cache вроде
HIT,MISS,X-Cache,CF-Cache-Status. - Временно отключите кэш-плагин и повторите сценарий с изменением адреса доставки.
- Если используется CDN, проверьте, не кэширует ли он HTML страницы корзины или оформления заказа.
- Сравните поведение для авторизованного и гостевого пользователя: иногда кэш ломает только гостей.
Если после отключения плагина проблема исчезла, значит, дело в page cache. Если нет — смотрите в сторону фрагментного кэша, AJAX-обновления или кастомной логики доставки.
Пошаговое решение: исключаем корзину, оформление заказа и страницы с динамической доставкой
Самый надёжный путь — исключить из кэша все страницы, где WooCommerce рассчитывает динамические данные. Для стандартного магазина это обычно корзина и оформление заказа. Если у вас есть отдельная страница с калькулятором доставки или подбором склада, её тоже стоит добавить в исключения.
1. Исключите страницы в кэш-плагине
В большинстве плагинов есть поле для URL, которые не нужно кэшировать. Туда обычно добавляют:
/cart//checkout//my-account/— если там есть персональные данные или динамические блоки;- страницы с калькулятором доставки или подбором пункта выдачи.
Если плагин позволяет исключать по шаблону, лучше использовать именно шаблон, а не отдельные URL, чтобы не пропустить локализованные или кастомные слаги.
2. Добавьте серверные заголовки для страниц WooCommerce
Если кэш управляется на уровне сервера или CDN, полезно явно пометить страницы как не предназначенные для публичного кэша. Для WordPress это можно сделать через send_headers или раньше — через template_redirect. Пример ниже не заменяет настройки CDN, но помогает снизить риск случайного кэширования HTML.
<?php
add_action( 'send_headers', function () {
if ( function_exists( 'is_cart' ) && ( is_cart() || is_checkout() || is_account_page() ) ) {
nocache_headers();
}
} );Этот код стоит использовать только если вы понимаете, как он сочетается с вашим кэш-плагином. Он не «лечит» уже настроенный CDN, но помогает WordPress отдавать корректные заголовки для чувствительных страниц.
3. Для нестандартных страниц добавьте условие по slug
Если у вас есть отдельная страница расчёта доставки, которую WooCommerce не считает стандартной корзиной или checkout, можно отключить кэш по slug. Это удобно, когда страница построена на шорткоде или кастомном шаблоне.
<?php
add_action( 'template_redirect', function () {
if ( is_page( array( 'delivery-calculator', 'shipping-options' ) ) ) {
nocache_headers();
}
} );Такой подход лучше, чем пытаться угадывать по GET-параметрам, потому что slug стабильнее и проще поддерживается в команде.
Если нужно оставить кэш страницы, но обновлять только доставку
Иногда полное отключение кэша слишком дорого: страница товара или корзины может быть тяжёлой, а трафик — высоким. Тогда лучше оставить HTML в кэше, но вынести расчёт доставки в AJAX и обновлять только фрагмент. Это уже не про page cache, а про динамический блок.
Для WooCommerce базовый механизм обновления фрагментов корзины уже есть, но кастомные блоки доставки часто нужно обновлять вручную. В таком случае логика обычно строится так: пользователь меняет адрес, фронтенд отправляет AJAX-запрос, сервер пересчитывает варианты доставки, а на странице обновляется только нужный контейнер.
<?php
add_action( 'wp_ajax_get_shipping_preview', 'my_get_shipping_preview' );
add_action( 'wp_ajax_nopriv_get_shipping_preview', 'my_get_shipping_preview' );
function my_get_shipping_preview() {
check_ajax_referer( 'shipping_preview', 'nonce' );
if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
wp_send_json_error( array( 'message' => 'Cart unavailable' ), 400 );
}
$packages = WC()->shipping()->get_packages();
$rates = array();
foreach ( $packages as $package ) {
$rates[] = WC()->shipping()->calculate_shipping_for_package( $package );
}
wp_send_json_success( array( 'rates' => $rates ) );
}Это упрощённый пример, но сама идея рабочая: кэшируете страницу, а не чувствительные расчёты. Для реального проекта важно корректно собирать данные доставки из текущей сессии и не полагаться на устаревшие значения из HTML.
Сравнение подходов: плагин, код или гибрид
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Исключение страниц в плагине кэша | Стандартные cart/checkout и несколько кастомных страниц | Быстро, без разработки | Не всегда покрывает CDN и серверный кэш |
| nocache_headers() через код | Нужен контроль на уровне темы или плагина | Работает точечно, прозрачно для WordPress | Не заменяет настройки внешнего кэша |
| AJAX для блока доставки | Нужно сохранить кэш страницы и обновлять только динамику | Лучше для производительности | Сложнее в поддержке и тестировании |
Как проверить, что решение сработало
Проверка должна быть не визуальной, а повторяемой. Иначе легко принять случайное совпадение за исправление.
- Откройте страницу корзины в инкогнито и убедитесь, что заголовок ответа не показывает кэшированный HTML для чувствительной страницы.
- Измените адрес доставки и проверьте, что список тарифов обновляется без перезагрузки старого значения.
- Сравните поведение после очистки кэша плагина и после истечения TTL — результат должен быть одинаковым.
- Проверьте мобильную и десктопную версию: иногда кэшируется только один шаблон.
- Если есть CDN, убедитесь, что он не отдаёт старую версию страницы по тому же URL.
Полезно открыть вкладку Network и посмотреть, какой именно запрос возвращает данные доставки: HTML страницы, AJAX-ответ или REST-запрос. Это сразу показывает, где ещё может сидеть кэш.
Частые ошибки и как их исправить
Отключили кэш только в плагине, но забыли про CDN
Внешний кэш продолжает отдавать старый HTML, даже если локальный плагин уже не кэширует страницу. Решение — добавить исключения и на уровне CDN, и на уровне сервера.
Исключили слишком много страниц
Если отключить кэш для всего магазина, производительность быстро просядет. Обычно достаточно cart, checkout и нескольких динамических страниц, а каталог и карточки товаров лучше оставить кэшируемыми.
Проверяют только после очистки кэша
Это плохой тест. Нужно проверить сценарий дважды: сразу после изменения адреса и после повторного открытия страницы в новой сессии. Иначе можно не заметить, что проблема возвращается при следующем визите.
Используют одинаковые правила для гостей и авторизованных
Для авторизованных пользователей кэш часто и так отключён или работает иначе. Если баг проявляется только у гостей, ищите именно page cache, а не логику WooCommerce.
Безопасность и производительность: что не стоит делать
Не храните в кэше HTML, который содержит персональные данные, адреса, телефоны, индивидуальные скидки или результаты расчёта доставки для конкретной сессии. Даже если кажется, что «всё работает», такой кэш может показать чужие данные следующему посетителю.
Если вам нужен быстрый магазин с динамической доставкой, лучше разделить задачи:
- статические части страницы отдавать из кэша;
- динамические блоки обновлять AJAX-запросом;
- чувствительные страницы исключать из page cache полностью;
- после изменений в правилах доставки очищать не только WordPress-кэш, но и CDN.
Для магазинов с нестандартной логикой доставки это обычно надёжнее, чем пытаться «уговорить» кэш хранить всё подряд. Если нужна более широкая чистка дублей и технических хвостов в WordPress, иногда помогает связка с инструментами вроде Clearfy Pro, но в этой задаче ключевое всё равно не в плагине, а в правильных исключениях и проверке цепочки кэша.