Это руководство разбирает слои кэширования типичного сайта на WordPress сверху вниз: что делает каждый слой, почему некоторые страницы его обходят, в каком порядке всё включать и как проверить результат реальными цифрами. Оно написано для владельцев сайтов и администраторов, которые могут редактировать wp-config.php и выполнить несколько команд по SSH.
Как устроены слои
Запрос к странице WordPress проходит несколько станций: браузер посетителя, веб-сервер с полностраничным кэшем, интерпретатор PHP с OPcache, объектный кэш и, наконец, MySQL. Каждый слой стоит перед следующим, и попадание в верхний слой означает, что всё, что ниже, не выполняет никакой работы. Попадание в полностраничный кэш полностью пропускает PHP и базу данных. Попадание в объектный кэш всё ещё выполняет PHP, но пропускает повторяющиеся запросы к базе. Поэтому слои не взаимозаменяемы: каждый помогает своему типу трафика.
Полностраничный кэш: самый большой выигрыш
Полностраничный кэш сохраняет готовый HTML страницы и отдаёт его следующему посетителю, вообще не запуская WordPress. Для анонимного трафика это самое крупное улучшение из возможных: ответ из кэша занимает несколько миллисекунд вместо нескольких сотен, потому что не выполняется ни PHP, ни один запрос к базе данных.
Страницы вошедших пользователей и корзины обходят этот кэш намеренно. Их HTML персонализирован: панель администратора, имя пользователя, содержимое корзины. Отдача кэшированной копии показала бы одному посетителю данные другого. Поэтому плагины кэширования и правила сервера пропускают кэш, как только видят такие cookie, как wordpress_logged_in_* или woocommerce_cart_hash. Практический вывод: магазин, где большинство покупателей вошли в аккаунт, получает от страничного кэша заметно меньше и сильно зависит от нижних слоёв.
Проверить, отдана ли страница из кэша, можно по заголовкам ответа:
curl -sI https://example.com/ | grep -i -E "x-cache|age|cache-control"
Объектный кэш: что на самом деле экономит Redis
По умолчанию WordPress при каждом запросе заново собирает всё из MySQL: автозагружаемые опции, метаданные пользователей и записей, связи таксономий, настройки плагинов, структуры меню. Большинство этих запросов возвращают один и тот же результат тысячи раз в день. Постоянный объектный кэш хранит эти результаты в памяти Redis, поэтому следующий запрос читает их, не обращаясь к базе данных.
Эффект максимален именно там, где полностраничный кэш бессилен: wp-admin, вошедшие пользователи, оформление заказа в WooCommerce, вызовы REST API. Некэшированный просмотр страницы часто выполняет 100 и более запросов; с прогретым Redis это число падает до нескольких десятков.
wp plugin install redis-cache --activate wp redis enable wp redis status
Если wp redis status показывает соединение и растущее число ключей, всё работает. Типичному сайту нужен скромный объём памяти Redis: обычно достаточно от 64 до 256 МБ.
OPcache: не компилируйте PHP при каждом запросе
PHP перед выполнением компилируется в байткод. Без OPcache интерпретатор перекомпилирует ядро WordPress, тему и все плагины, а это несколько тысяч файлов, при каждом запросе. OPcache держит скомпилированный байткод в общей памяти, поэтому эта цена платится один раз после изменения кода, а не постоянно.
Любая современная сборка PHP включает OPcache, и для веб-сервера он обычно включён. Проверяйте его через веб-SAPI, а не через командную строку: php -r выполняется в CLI, где opcache.enable_cli по умолчанию выключен, поэтому проверка из CLI сообщает false даже тогда, когда в PHP-FPM OPcache работает нормально. Положите временный файл в корень сайта, запросите его по HTTP, затем удалите:
echo ' /var/www/html/opcache-check.php curl -s https://example.com/opcache-check.php rm /var/www/html/opcache-check.php
bool(true) означает, что OPcache активен для реальных веб-запросов. Разумные настройки php.ini для WordPress: opcache.memory_consumption=192 и opcache.max_accelerated_files=20000. Если вы обновляете код копированием файлов, оставьте opcache.validate_timestamps=1, чтобы изменения подхватывались.
Кэширование в браузере и форматы изображений
Дешевле всего обходится запрос, который браузер вообще не отправляет. Статические ресурсы: CSS, JavaScript, шрифты и изображения, стоит кэшировать на стороне клиента надолго. WordPress добавляет к подключаемым ресурсам параметр ?ver=, поэтому долгий срок хранения безопасен: когда файл меняется, меняется и его URL. Типичное правило nginx:
location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|avif|woff2)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
Формат изображения значит не меньше, чем его кэширование. WebP обычно на 25 или даже 30 процентов меньше эквивалентного JPEG, а AVIF ещё на 15 или 20 процентов меньше WebP ценой более медленного кодирования. Конвертируйте при загрузке плагином или cron-задачей, сохраняйте оригинал как запасной вариант и не перекодируйте уже оптимизированные файлы: каждое сжатие с потерями снижает качество.
Порядок работ, измерения и миф о пяти плагинах
Включайте слои в таком порядке и измеряйте после каждого шага, а не один раз в конце:
- Проверьте OPcache. Это фундамент, он не несёт риска и не требует плагина.
- Полностраничный кэш. Самый большой выигрыш для анонимного трафика.
- Объектный кэш Redis. Помогает вошедшим пользователям, wp-admin и WooCommerce, то есть трафику, который страничный кэш обслужить не может.
- Кэширование в браузере и заголовки expires.
- WebP или AVIF для изображений.
Следить нужно за TTFB, временем до первого байта, потому что слои кэширования срабатывают до того, как первый байт покидает сервер:
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s total: %{time_total}s\n" https://example.com/
Выполните команду 5 раз и отбросьте первый результат: он может попасть в холодный кэш. Некэшированная страница WordPress обычно показывает TTFB от 300 до 800 мс; попадание в полностраничный кэш должно оставаться заметно ниже 100 мс.
Наконец, миф: установка пяти плагинов кэширования не даёт пятикратного ускорения. Два страничных кэша отдают устаревшие копии друг друга, двойная минификация ломает JavaScript, а очистка в одном плагине не задевает копию, которую держит другой. Используйте один инструмент на слой и предпочитайте страничный кэш на уровне сервера, а не внутри PHP.
На наших тарифах WordPress хостинга весь этот набор, страничный кэш на уровне сервера, Redis и OPcache, уже настроен, так что из списка выше остаётся только измерение. Если вы хотите настроить всё самостоятельно, те же слои поддерживает любой из наших тарифов хостинга сайтов.