B2BPRO.KZ | Рекламное агентство в Алматы

Кэширование WordPress: как ускорить сайт без потери функциональности

Схема слоёв кэширования WordPress: запрос проходит через уровни кэша до базы данных

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

Проблема почти никогда не в самих плагинах. Она в том, что кэширование WordPress устроено слоями, каждый слой ведёт себя по-своему, и включать их вслепую опасно. Ниже разбор всех уровней кэша, точки, где он ломает работу сайта, и порядок внедрения, при котором ускорение не оборачивается потерянными заявками.

Из каких слоёв состоит кэш на сайте WordPress

Официальная документация WordPress выделяет четыре типа кэширования, и они действительно разные по природе.

Страничный кэш сохраняет готовый HTML страницы и отдаёт его следующему посетителю без обращения к PHP и базе данных. Именно он даёт основной прирост скорости для анонимных посетителей и именно он чаще всего ломает динамику.

Браузерный кэш работает на стороне посетителя. Через HTTP-заголовки Cache-Control и Expires сервер сообщает браузеру, как долго можно хранить картинки, стили и скрипты локально. Это уменьшает количество запросов при повторных визитах и почти ничего не ломает.

Объектный кэш перекладывает данные из медленного хранилища в быстрое: результаты запросов к базе, настройки, метаданные. Работает через Redis, Memcached или APC.

Серверный кэш включает кэш байт-кода PHP (OPcache, WinCache) и обратные прокси вроде Varnish. Эти слои живут вне WordPress и настраиваются на уровне хостинга.

Ошибка, которая тянется годами: считать «кэшем» только четвёртый пункт из списка плагинов и не трогать остальное. В результате сайт с включённым страничным кэшем всё равно тормозит в админке, потому что объектного кэша нет, а база выполняет одни и те же запросы на каждой загрузке.

Почему сайт «летает» у вас и тормозит у клиента

Типичный спор с подрядчиком: «у меня открывается за секунду». Обычно оба правы, просто измеряют разное.

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

Второй источник расхождений это прогретый и холодный кэш. Первый посетитель конкретной страницы после сброса кэша оплачивает полную генерацию, остальные получают готовый результат. Если проверять скорость сразу после очистки, цифры будут заметно хуже реальных. Отсюда практическое правило замеров: тестируйте страницу дважды, в режиме инкогнито, и смотрите на второй результат.

Третий момент касается географии. Посетитель из Алматы и сервер в Европе дают ощутимую задержку сети, на которую плагин кэша не влияет. Здесь помогает CDN или переезд ближе к аудитории, а не очередной оптимизатор.

Страничный кэш: где он живёт технически

Полезно понимать механику, потому что она объясняет большинство конфликтов. Страничный кэш подключается через файл-дропин: WordPress загружает advanced-cache.php из каталога wp-content, когда определена константа WP_CACHE. За загрузку отвечает фильтр enable_loading_advanced_cache_dropin, которым эту логику можно отключить.

Проверить, что происходит на конкретном сайте, можно без доступа к серверу. В админке на странице «Плагины» появляется вкладка «Drop-ins», где перечислены установленные дропины. Если там числится advanced-cache.php без предупреждений, страничный кэш подключён и работает.

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

Из нашей практики: сайт на WooCommerce отдавал ошибку 500 сразу после установки небольшого служебного плагина, который при выполнении дёргал сброс кэша. Причина была в конфликте с оставшимся дропином. Лечение заняло минуту (файл advanced-cache.php переименовали, сайт поднялся), а поиск причины занял час, потому что журнал ошибок указывал на совершенно другое место.

Объектный кэш: то, о чём просит «Здоровье сайта»

Многие впервые слышат про объектный кэш, когда WordPress в разделе «Здоровье сайта» рекомендует его включить. Проверки Persistent Object Cache и Page Cache добавили в ядро в версии 6.1, и они запускаются только в production-окружении. Хостинг-провайдеры могут менять текст рекомендации и пороги срабатывания через фильтры, поэтому формулировка у разных хостеров отличается.

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

Постоянный объектный кэш подключается тем же способом, что и страничный, через дропин object-cache.php в каталоге wp-content. Его ставит плагин Redis или Memcached, после чего WordPress перестаёт использовать встроенный класс и обращается к внешнему хранилищу. Здесь есть распространённое заблуждение: одна лишь строчка define('WP_CACHE', true) в wp-config.php ничего не ускоряет, пока не установлен соответствующий плагин и не создан дропин.

Практический эффект объектного кэша заметен там, где страничный бессилен: в админке, в личном кабинете, на страницах поиска и фильтрации, у авторизованных пользователей. Для интернет-магазина с сотнями товаров и активными менеджерами это часто важнее, чем ещё сто миллисекунд на главной.

Транзиенты: кэш, который пишет разработчик

Есть четвёртый слой, о котором владелец сайта обычно не подозревает, хотя оплачивает его последствия. Transients API позволяет сохранить результат тяжёлой операции на заданное время: курс валют, выборку популярных товаров, ответ внешнего API.

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

Важная деталь, на которой ломаются самописные интеграции: указанное время жизни это максимум, а не минимум. Официальная документация формулирует прямо: транзиент может исчезнуть через секунду или пролежать сутки, но никогда не переживёт свой срок. Код обязан уметь пересчитать значение в любой момент. Если интеграция предполагает, что данные точно пролежат час, она сломается в первый же день после подключения Redis.

Где кэш ломает функциональность

Это та часть, которую стоит прочитать до включения кэша. Обычно её изучают уже после первых жалоб клиентов.

Корзина, оформление заказа, личный кабинет. Документация WooCommerce требует исключать страницы Cart, Checkout и My Account из полностраничного кэша, потому что их содержимое зависит от сессии конкретного покупателя. Часть связок настроена корректно из коробки: WooCommerce нативно совместим с WP Super Cache и сам сообщает ему не кэшировать эти страницы. Для WP Rocket документация просит убедиться, что три страницы внесены в исключения вручную. Для Varnish в документации приведено правило, пропускающее мимо кэша адреса вида /cart, /checkout, /my-account/*, /wc-api/*, выход из аккаунта и восстановление пароля.

Формы и защитные токены. WordPress защищает отправку форм одноразовыми числами (nonce), у которых ограниченный срок жизни. Когда страница с формой закэширована надолго, посетитель получает старый токен, и отправка падает с ошибкой безопасности. Обычно лечится исключением страницы из кэша или включением в плагине специального режима для форм.

Персонализированные фрагменты. Счётчик товаров в корзине в шапке, блок «вы смотрели», приветствие по имени. Если такой блок попал в общий HTML, все посетители увидят данные первого. Решение зависит от плагина: часть умеет подгружать динамические фрагменты отдельным запросом, часть требует выносить блок в AJAX.

Цены, остатки, акции. Магазин с частой сменой цен и коротким остатком на складе нуждается в разумном времени жизни кэша и в сбросе по событию. Кэш на сутки для товарных карточек в такой ситуации приводит к заказам по несуществующим ценам.

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

Как выбрать плагин кэша

Официальная документация WordPress в качестве быстрого решения называет W3 Total Cache, WP Super Cache и Cache Enabler. Это разумная отправная точка, но выбирать плагины кэша проще от инфраструктуры сайта, чем по рейтингам и обзорам. Кэширование WordPress везде опирается на одни и те же механизмы ядра, поэтому решает не название плагина, а то, насколько он дружит с вашим сервером и вашим типом сайта.

Если сервер работает на LiteSpeed, логично использовать родной плагин этого веб-сервера: он умеет отдавать кэш на уровне сервера, не поднимая PHP. Если у хостинга есть собственный серверный кэш (nginx, Varnish, платформенный кэш), сначала стоит разобраться, что он уже кэширует, чтобы не строить второй такой же слой поверх. Если ничего этого нет, подойдёт любой из перечисленных плагинов, и разница между ними будет меньше, чем разница между «настроен» и «поставлен по умолчанию».

При сравнении плагинов смотрите на три вещи: умеет ли он исключать URL и cookie, есть ли сброс кэша по событию (публикация записи, изменение товара, поступление заказа) и предусмотрена ли поддержка динамических фрагментов. Оптимизация CSS и JavaScript в том же плагине это отдельная функция, которая ломает вёрстку чаще, чем сам кэш, поэтому включать её нужно отдельно и проверять каждую опцию.

Порядок внедрения, при котором ничего не падает

Последовательность, которой мы придерживаемся при разработке и сопровождении сайтов на WordPress, выглядит так.

  • Замер до изменений. Зафиксируйте время ответа сервера и время загрузки для трёх типовых страниц: главная, категория, карточка товара или статья. Без этой точки отсчёта спор об эффекте будет бесконечным.
  • Копия сайта. Кэш настраивается на тестовой копии, а не на живом магазине в разгар дня. Если копии нет, включайте по одной опции в самое тихое время суток.
  • Сначала базовое, потом агрессивное. Включите страничный кэш и браузерный, проверьте сайт, дайте ему поработать сутки. Объединение и минификация ресурсов, отложенная загрузка, критический CSS идут следующими шагами и всегда по одному.
  • Исключения до запуска, а не после. Корзина, оформление, личный кабинет, страницы с формами, служебные адреса интеграций. Для магазина этот список составляется в первую очередь.
  • Проверка в трёх ролях. Пройдите сценарий гостем в режиме инкогнито, авторизованным покупателем и администратором. Положите товар в корзину, оформите тестовый заказ, отправьте форму, оставьте комментарий.
  • Повторный замер и наблюдение. Через неделю сравните цифры и посмотрите на конверсию: рост скорости при падении заявок означает, что где-то кэш съел динамику.

Как убедиться, что кэш действительно работает

Бывает и так: кэш формально включён, а фактически до посетителя не доходит. Причины бывают разные: несовместимая конфигурация сервера, cookie, которую ставит какой-нибудь чат или счётчик каждому посетителю, отключённая перезапись правил. Плагин при этом рапортует, что всё в порядке.

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

Второй способ точнее. Многие плагины и серверные кэши помечают свою работу: добавляют собственный заголовок ответа или служебный комментарий в конце HTML-кода страницы. Посмотреть их можно там же, в инструментах разработчика, либо запросом curl с выводом заголовков. Если такой пометки нет ни в одном обращении, страница до кэша не дошла.

Третий признак виден по нагрузке. После корректного включения страничного кэша расход процессорного времени на хостинге заметно падает, потому что большинство запросов перестаёт поднимать PHP. Если панель хостинга показывает прежнюю нагрузку при выросшем трафике, значит кэшируется в лучшем случае малая часть страниц.

Проверять стоит не только главную. Разные типы страниц (категория, карточка, статья, страница с формой) настраиваются по-разному и попадают под разные исключения, поэтому берите для проверки минимум четыре адреса.

Что делать, когда кэш «залип»

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

Порядок действий стоит держать в таком виде. Сначала сброс в плагине кэша. Затем серверный кэш, если хостинг его предоставляет: nginx, LiteSpeed, Varnish, платформенный кэш панели управления. Потом CDN, если он подключён, поскольку он хранит копию независимо от сайта. И только в конце браузер, где достаточно открыть страницу в режиме инкогнито, чтобы понять, локальная это проблема или нет.

Если после всех сбросов страница по-прежнему старая, проверьте вкладку «Drop-ins» на странице плагинов. Оставшийся от прежнего плагина advanced-cache.php продолжает работать, даже когда сам плагин давно удалён, и кнопка сброса в новом плагине его не касается.

Кэш не лечит тяжёлый сайт

Полезно понимать границы метода. Страничный кэш прячет тяжесть сайта от анонимного посетителя, но ничего не меняет для тех, кто работает в системе. Если сайт генерирует страницу три секунды из-за полусотни активных плагинов, неоптимальных запросов к базе и темы, которая грузит все шрифты сразу, то администратор, менеджер и покупатель в личном кабинете будут ждать эти три секунды каждый раз.

Признак, что кэшированием проблему уже не закрыть: сайт быстрый для гостя и мучительный в админке; после каждой публикации скорость проседает на несколько минут; хостинг регулярно жалуется на превышение лимитов CPU. В такой ситуации помогает аудит запросов и плагинов, чистка автозагружаемых опций в базе, пересборка шаблонов, иногда переход на другой хостинг. Работа менее эффектная, чем установка плагина, зато результат держится, и кэш поверх неё уже действительно ускоряет сайт, а не прикрывает его проблемы. Если по вашему сайту непонятно, где проходит эта граница, мы разбираем такие случаи в рамках услуг по разработке и доработке сайтов: сначала измеряем, потом чиним причину, и только затем настраиваем кэш.

Частые вопросы

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

Можно ли включить кэш на интернет-магазине?
Можно и нужно, но с исключениями. Документация WooCommerce требует держать вне полностраничного кэша страницы корзины, оформления заказа и личного кабинета. С WP Super Cache эти исключения работают из коробки, для других плагинов их задают вручную. Отдельно проверьте счётчик корзины в шапке и любые блоки, которые зависят от конкретного покупателя.

Что такое «постоянный объектный кэш», который просит включить «Здоровье сайта»?
Это внешнее хранилище (обычно Redis или Memcached), которое сохраняет результаты запросов между обращениями к сайту. Встроенный объектный кэш WordPress хранит данные только в пределах одного запроса, поэтому каждый следующий посетитель заставляет систему делать ту же работу заново. Подключается плагином, который создаёт дропин object-cache.php в каталоге wp-content.

Почему после включения кэша перестала отправляться форма?
Скорее всего, дело в одноразовых токенах (nonce), которые WordPress использует для защиты отправки. У них ограниченный срок жизни, и в закэшированной странице токен успевает устареть. Страницу с формой исключают из кэша либо включают в плагине режим, обновляющий такие данные отдельным запросом.

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

Прокрутить вверх