Любой, кто стремится улучшить производительность своего WordPress-сайта, неизбежно обращается к кэшированию. Да, сегодня есть много плагинов страничного кэширования, однако они не всесильны. Потенциал по дополнительным улучшениям всегда имеется.
Если вы читали блог Delicious Brains, то вы знаете, что я ярый сторонник Nginx FastCGI Caching. Он невероятно быстр и относительно прост в настройке. Однако у него есть свои особенности, о чем мы уже говорили в недавней статье. В частности, у Nginx FastCGI Caching есть проблемы с инвалидацией кэша.
Все сервисы на Linux-сервере выполняются от имени конкретного системного пользователя. Nginx FastCGI Caching прекрасно работает в том случае, если под одним пользователем запущены Nginx и PHP. Файлы, кэшируемые Nginx, остаются доступными для PHP, т.е. вы можете очистить кэш прямо из PHP. Это особенно важно при публикации или обновлении записей в WordPress. Однако Nginx будет всегда создавать файлы кэша под текущим пользователем, и невозможно настроить владельца или группу этих файлов. Все кэшированные файлы создаются с правами доступа 0600 или 0700 для файлов и папок соответственно, и изменить это нельзя. Если Nginx и PHP работают под разными системными пользователями (что часто бывает), вы не сможете инвалидировать кэш из PHP.
Поскольку мы не можем задавать права доступа к файлам в Nginx, нам остается только создавать файлы кэша через PHP. Здесь мы плавно подходим к плагинам кэширования в WordPress. Если же вы посмотрите на результаты нашего последнего набора тестов, вы увидите, что Simple Cache не отвечает производительности, предлагаемой Nginx FastCGI Caching.
Сравнение RPS (количества запросов в секунду):
- WordPress – 31
- Simple Cache – 281
- FastCGI Cache – 420
- Varnish – 337
Почему так происходит? Давайте посмотрим, как работают плагины страничного кэширования.
Как работают плагины страничного кэширования в WordPress
Безусловно, самое узкое место в WordPress – это подключение к серверу БД и запрос данных. Подключение производится для каждого отдельного запроса вне зависимости от того, менялись ли данные между запросами. Это крайне неэффективно.
Плагины страничного кэширования WordPress решают эту проблему, создавая статичную HTML-версию запрашиваемых данных, которая обычно хранится в файловой системе. Последующие запросы работают уже со статичным HTML-файлом; не нужно повторно обращаться к БД и обрабатывать страницу. Чтобы сделать это, плагины страничного кэширования используют файл advanced-cache.php, который создается при установке плагина. Он запускается до загрузки WordPress (если константа WP_CACHE равна true). Ядро WP обрабатывает его в wp-settings.php:
if ( WP_CACHE && apply_filters( 'enable_loading_advanced_cache_dropin', true ) && file_exists( WP_CONTENT_DIR . '/advanced-cache.php' ) ) { // For an advanced caching plugin to use. Uses a static drop-in because you would only want one. include WP_CONTENT_DIR . '/advanced-cache.php'; // Re-initialize any hooks added manually by advanced-cache.php. if ( $wp_filter ) { $wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter ); } }
Многие плагины кэширования встраивают дополнительную логику, которая запускается из advanced-cache.php, но обычно все сводится к простой проверке (file_exists) существования статичного HTML-файла. Если файл существует, то его содержимое считывается и записывается в выходной буфер. Затем скрипт завершает свою работу, что не позволяет WordPress выполнить оставшуюся часть запроса. Примечание: все, что подцеплено к хуку shutdown, будет по-прежнему выполнено.
Простейший пример:
if ( @file_exists( $path ) && @is_readable( $path ) ) { @readfile( $path ); exit; }
Лучшие плагины кэширования для WordPress
Теперь, когда мы знаем, как работают плагины кэширования, давайте рассмотрим несколько популярных решений. Базовая реализация плагинов практически одинакова, а потому производительность зачастую тоже равнозначна. Поэтому в статье мы будем анализировать доступный функционал и простоту использования.
WP Rocket
WP Rocket – один из лучших доступных плагинов для кэширования WordPress. Это премиум-плагин, стоимость которого начинается от 49$ за один сайт. Бесплатная версия отсутствует, хотя есть 14-дневная гарантия возврата средств.
Это единственный платный плагин в нашем списке, и он занимает первое место с точки зрения функционала и простоты использования. Страничное кэширование включается автоматически после активации плагина. Простой и понятный интерфейс позволяет дополнительно оптимизировать и настроить правила кэширования.
WP Rocket имеет широкую совместимость с разными плагинами, темами и хостингами. Он прекрасно работает с ecommerce-плагинами, включая WooCommerce. WP Rocket полностью совместим со многими хостингами, у которых имеются свои решения для страничного кэширования. Это означает, что конфликтов не произойдет.
Другие функции, входящие в WP Rocket:
- Оптимизация файлов CSS и JavaScript.
- Ленивая загрузка медиафайлов.
- Предварительная загрузка кэша (preload)
- Интеграция с CDN
- Оптимизация базы данных.
WP Super Cache
WP Super Cache – бесплатный плагин для кэширования с открытым кодом от Automattic, компании, стоящей за WordPress.com. Это один из самых популярных плагинов кэширования – более 2 млн активных установок.
Хотя в WP Super Cache не так много дополнительных функций, он в целом работает хорошо, а пользовательский интерфейс простой и понятный. В режиме Easy вы можете включить страничное кэширование одним переключателем. Режим Advanced дает контроль над другими параметрами кэша.
Дополнительные возможности WP Super Cache
- Сборка мусора для очистки устаревших файлов кэша.
- Предварительная загрузка кэша (preload)
- Интеграция CDN
W3 Total Cache
W3 Total Cache – еще один популярный плагин, насчитывающий более 1 млн активных установок. У него есть платные опции – к примеру, премиум-поддержка, а также Pro-версия с некоторыми дополнительными функциями.
W3 Total Cache имеет массу опций, однако он не так прост в использовании, а потому новичков он может отпугнуть. Однако в нем имеется руководство, которое позволит быстро начать работу.
Функционал:
- Минификация HTML, CSS and JavaScript.
- Объектное кэширование
- Кэширование базы данных.
- Кэширование PHP OPCode.
- Ленивая загрузка изображений.
- Оптимизация браузерного кэширования.
Почему плагины кэширования работают плохо с Nginx
Плагины кэширования WordPress позволяют значительность повысить производительность, однако они проигрывают по сравнению с Nginx FastCGI Caching. Почему так? Потому что каждый запрос обрабатывается PHP, что требует гораздо больше CPU-циклов, нежели простая обработка запроса в Nginx.
Если вы помните старые добрые времена, когда на рынке лидировал Apache, то вы знаете, что большинство плагинов кэширования рекомендовали добавить правило mod_rewrite в ваш файл .htaccess. Это позволяло Apache обрабатывать запрос, не касаясь PHP. Дело в том, что Apache мог перезаписывать конфиги в процессе выполнения с помощью .htaccess. Однако Nginx это не поддерживает.
Если бы мы могли заставить Nginx выполнять аналогичную проверку file_exists, как в PHP, то мы, вероятно, смогли бы существенно повысить производительность плагинов кэширования WP.
Как заставить плагины кэширования WordPress «летать»
Как оказалось, Nginx действительно выполняет аналогичную проверку file_exists для каждого обрабатываемого запроса. В большинстве конфигов Nginx есть следующий блок.
location / { try_files $uri $uri/ /index.php?$args; }
По сути, это указывает Nginx передать запрашиваемый файл, если он существует, или в противном случае выполнить внутренний редирект на index.php. Если мы добавим нашу директорию кэша в этот блок, мы сможем передавать кэшированный HTML-файл из Nginx напрямую, не обращаясь к PHP.
Давайте для примера возьмем W3 Super Cache. Он хранит файлы кэша следующим образом:
// Request: hellfish.media/ wp-content/cache/supercache/hellfish.media/index-https.html // Request: hellfish.media/hello-world/ wp-content/cache/supercache/hellfish.media/hello-world/index-https.html
Как вы можете видеть, путь к кэшированному файлу index-https.html в каталоге кэша плагина всегда совпадает с запрошенным URL.
Теперь мы можем обновить нашу директиву try_files, чтобы использовать переменные $http_host и $request_uri:
location / { try_files "/wp-content/cache/supercache/$http_host/$request_uri/index-https.html" $uri $uri/ /index.php?$args; }
После перезагрузки Nginx любые кэшированные страницы, генерируемые W3 Super Cache, будут поступать напрямую из Nginx, игнорируя PHP. Запросы, которые не были кэшированы, будут по-прежнему обрабатываться WordPress, и система будет формировать кэш для последующих запросов.
Аналогично в случае с WP Rocket:
location / { try_files "/wp-content/cache/wp-rocket/$http_host/$request_uri/index-https.html" $uri $uri/ /index.php?$args; }
Для более продвинутой конфигурации Nginx под WP Rocket мы советуем воспользоваться пакетом rocket-nginx.
Для W3 Total Cache, если вы используете метод страничного кэширования «Disk: Enhanced», вы можете указать следующее:
location / { try_files "/wp-content/cache/page_enhanced/$http_host/$request_uri/_index_ssl.html" $uri $uri/ /index.php?$args; }
Также для W3 Total Cache есть хороший вариант включения сгенерированного файла nginx.conf в конфигурации Nginx для вашего сайта. Этот файл автоматически обновляется в соответствии с вашими настройками W3 Total Cache.
Тесты
Пришло время сравнить результаты. Как и в прошлом случае, я буду использовать ApacheBench.
ab -n 10000 -c 100 https://siteunderload.com/
Здесь мы имитируем передачу 10 000 запросов с одновременным выполнением 100 запросов. Каждый тест будет выполняться в общей сложности 10 раз, и для сравнения будет использоваться среднее значение.
Серверный стек выглядит следующим образом (каждый сайт работает по HTTPS):
- DigitalOcean 1GB ($5/месяц)
- Ubuntu 20.04
- PHP 8.0
- Nginx 1.20.1
- MySQL 8.0.25
- WordPress 5.8, Twenty Twenty-One
Количество запросов в секунду (RPS)
Начнем с запросов в секунду, то есть с количества одновременных пользователей, которое может обрабатывать ваш сервер (чем больше, тем лучше). Как видим, все плагины с базовыми настройками страничного кэширования работают примерно одинаково, а вот Nginx FastCGI Cache существенно лидирует.
- WP Rocket – 268
- WP Super Cache – 272
- W3 Total Cache – 238
- Nginx FastCGI Cache – 407
Однако использование Nginx-директивы try_files с плагинами кэширования дает похожие на Nginx FastCGI Caching результаты. В некоторых случаях даже чуть лучше.
- WP Rocket – 412
- WP Super Cache – 408
- W3 Total Cache – 404
- Nginx FastCGI Cache – 407
Среднее время ответа (мс)
Среднее время ответа – это общее время, требуемое для выполнения запроса (чем меньше, тем лучше). Это среднее значение для всех 10000 запросов – имитация времени ответа, когда сервер находится под нагрузкой. Как и выше, с включенной директивой try_files результаты похожи на Nginx FastCGI.
- WP Rocket – 244
- WP Super Cache – 246
- W3 Total Cache – 249
- Nginx FastCGI Cache – 247
Заключение
Как и ожидалось, использование плагина кэширования с Nginx-директивой try_files существенно улучшает производительность и поднимает ее до нативного кэширования FastCGI Caching в Nginx.
На практике разница между Nginx FastCGI Caching и плагинами с директивой try_files незначительна, и любое из этих решений для кэширования является отличным вариантом. Если вы используете администрируемый хостинг, вам, вероятно, не потребуется плагин для страничного кэширования, поскольку такие решения уже встроены в данные сервисы. В противном случае я бы порекомендовал попробовать разные плагины, чтобы выбрать для себя самый удобный.
Источник: spinupwp.com