В этой части я подробно рассмотрю принцип работы каждого плагина, о которых говорил в первой части, а также приведу код с доработками для закрытия проблем плагинов. Кратко все преимущества и недостатки, основные выводы я уже сделал в первой части статьи.
Напомню, что я определял для себя следующие требования к плагинам:
Настройки WP Super Cache
Почему именно так? И почему многие настройки отличаются от рекомендованных разработчиком и рекомендаций со StackOverflow.
Настройки WP Super Cache
Отключаем таймаут кеширования. Позже мы включим автокеширование, которое не позволит очищать автоматически созданные файлы, при этом созданные кеш-файлы по заходам пользователей из рекламы будут удаляться по таймауту. Но нам это не нужно, эти файлы будут удалены при следующем запуске автокеширования, а если мы укажем таймаут меньше, чем интервал запуска автокеширования - они попросту удаляться раньше, чем нужно. Поэтому устанавливаем значение: "0", при этом не стоит переживать за накопление мусора, при запуске автокеширования ВЕСЬ мусор будет удален.
Далее переходим на вкладку «Общий кеш», где реализуем автокеширование.
Настройка WP Super Cache
Нужно проставить все галки, а также подобрать оптимальный период обновления кеша для настраиваемого сайта.
Не стоит указывать слишком большой промежуток обновления кеша, чтобы при публикации контента, который доступен на нескольких страницах, не попасть в ситуацию, когда была опубликована новость или важный пресс-релиз, а на сайте эта публикация появляется только спустя сутки.
Да, WP Super Cache самостоятельно обновит кеш страницы при внесении в неё изменений, НО он не будет обновлять другие страницы, где может присутствовать эта запись (например, на главной, в подвале или в сайдбаре).
Слишком маленький промежуток устанавливать тоже не стоит, т.к. при запуске автокеширования будут удалены все кеш-файлы, которые были созданы, в том числе неавтоматическим способом (например, при переходе из рекламы), и пользователи, заходя на эти страницы, будут опять видеть медленную загрузку.
В общем, если на сайте активно публикуются новости или статьи, стоит указать промежуток от 1 до 2 часов. Если же сайт по большей части статичный, и на нём редко что-либо публикуется или редактируется, спокойно можно выставить интервал в 24 часа.
Также полезно будет включить галку у параметра «Сообщения о статусе кэша» на вкладке «Обслуживание», для того чтобы периодически поглядывать, когда фактически был создан кеш той или иной страницы, не отвалилось ли кеширование в принципе, нет ли проблем с автоматическим кешированием.
На этом настройка плагина завершена.
Разработчики плагина как будто бы знали о такой проблеме, потому что предусмотрели настройку «Не кешировать страницы с параметрами GET (?x=y в конце URL)». Тем не менее, она ничего не даёт, кроме экономии места на диске, потому что кеш не будет создаваться для страниц с GET-параметрами.
Единственный способ избежать этой проблемы - это «колхозить» плагин. Колхоз и допилы чужих решений - это то, за что я проклинаю всех разработчиков, потому что так делать нельзя (как минимум, после обновления плагина - все твои изменения будут отменены).
Ничего умнее я не смог придумать, как добавить в файл wp-content/plugins/wp-super-cache/wp-cache-phase1.php следующий код:
function removeGetParameter($url, $varname) {
return preg_replace('#\\?$#', '', preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','$1',$url));
}
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_source");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_medium");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_campaign");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_content");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_term");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "gclid");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "yclid");
после строчки $wp_cache_request_uri
Это позволяет указать плагину на то, какую страницу мы хотим достать из кеша, при этом не перенаправляя никуда пользователя (в адресной строке UTM-метки у пользователя останутся).
В итоге, проблема устранена, но не до конца. Даже если страница https://www.site.com/landing-page/ была ранее уже закеширована, при попытке зайти по ссылке https://www.site.com/landing-page/?...o-buy-something&yclid=93473892748392743473829 рядом создается еще один файл кеша (естественно страница грузится медленно). В разделе «Статистика кеша» на странице плагина мы увидим 2 идентичных элемента: https://www.site.com/landing-page/ в разделе "WP Super Cached Files" и точно такую же https://www.site.com/landing-page/ в разделе "WP Fresh Cached Files". Тем не менее, до момента истечения срока жизни кеша, при попытке обратиться с любым набором из описанных GET-параметров, который мы «приколхозили» с любым их значением (например, https://www.site.com/landing-page/?gclid=666), пользователю уже будет отдаваться кешированная версия (т.е. страница загрузится быстро).
Таким образом, если реклама ведется только на одну страницу сайта, а срок жизни кеша 1 час, то раз в час один пользователь будет грузить страницу медленно (пока создается кеш), при этом все остальные пользователи будут получать страницу быстро, ровно, как и те люди, которые заходят на сайт из поиска или по другим источникам без GET-параметров.
Ситуация стала значительно лучше, но до сих пор не идеальна. Представим, что реклама ведется на 100 страниц, реклама очень сильно таргетированная и с урезанными бюджетами. Так что не факт, что в час хотя бы один человек зайдет на ту или иную страницу (по рекламе). В этом случае профит не столь очевидный. При таком раскладе каждый привлеченный по рекламе человек будет долго ждать пока страница будет загружена.
Перелопатив тысячи строк кода, я так и не нашел способ это победить. Поэтому для себя, пока что, я нашел очень «костыльный», но всё же работающий способ решить эту проблему:
Да, в лоб, но это работает! Если кто-то найдет более элегантный способ подружить WP Super Cache с GET-параметрами - приглашаю в комментарии.
Во-первых, возможности выбора метода доставки кеша (mod_rewrite или PHP) нет, он работает исключительно через mod_rewrite, поэтому реализовать кастомный трекинг (как и любую другю PHP-логику) невозможно.
Во-вторых, автокеширование даже сравнительно небольшого сайта (~100 страниц) убивает напрочь сервер, на котором он крутится (скорее всего WP Rocket пытается осуществить обход всех страниц разом).
В-третьих, уже созданный кеш на половине страниц отваливается буквально через пару минут после его создания по неизвестной причине.
В общем, я даже не стал тратить время на доработки этого плагина.
Тем не менее для меня критичными оказались 2 проблемы:
Увеличивать время жизни кеша не хочется. Да, при обновлении страниц или новостей кеш для них автоматически будет обновлен, но на других страницах, куда могут быть подгружены эти записи, например, на главную, кеш обновлен не будет, а соответственно, добавленная или измененная запись там не появятся ровно до тех пор, пока не истечет время жизни предыдущего кеша.
Тем не менее в случае, если нет желания дорабатывать WP Super Cache, то W3 Total Cache вполне себе альтернатива. Также W3 Total Cache отлично подойдет для статичных сайтов, где можно обновлять кеш раз в сутки - запустил один раз ночью, и пусть он всё обновляет пока на сайте трафика мало. Либо вообще не использовать функцию автокеширования и обновлять кеш вручную при изменении сайта.
Настройка W3 Total Cache
Настройка W3 Total Cache
Включаем автокеширование ("Автоматическая настройка кеша страницы"), указываем интервал обновления (минимум 60 секунд, т.к. WP Cron не умеет работать быстрее), указываем кол-во страниц в интервале - выбираем в зависимости от скорости загрузки страниц без применения кеширования (если без кеширующего плагина в среднем TTFB страниц ~5 сек., то стоит указать кол-во не более 12, чтобы не нагружать лишний раз сервер). Также необходимо указать путь к Sitemap.XML, на основе которого будет осуществляться обход сайта. Рекомендую использовать для построения Sitemap.XML плагин "Yoast SEO", т.к. для интеграции с Yoast SEO у W3 Total Cache есть отдельное расширение, а это значит, что сайтпамы, сгенерированные Yoast SEO будут поглощаться плагином W3 Total Cache без каких-либо ошибок.
Чтобы отключить автокеширование у плагина W3 Total Cache достаточно поставить 0 в интервале обновления.
Далее спускаемся к разделу "Advanced":
Настройка W3 Total Cache
В блоке "Принятые строки запроса" указываем те GET-параметры URL-адресов, которые мы не хотим кешировать отдельно. Также укажем значения "Максимальное время жизни кэшированых объектов" и "Период удаления устаревшего кэша" в зависимости от того как часто мы хотим обновлять кеш. Нажимаем "Сохранить настройки и очистить кэш". На этом настройка плагина завершена.
Выше я уже писал о том, что периодически, несмотря на то, что кеш для определенных страниц уже создан, они все равно грузятся медленно. Частично исправить эту проблему поможет включение PHP-расширения "Zend Opcache" на сервере с сайтом.
Тем не менее вторую проблему (долгая загрузка страниц в период обновления кеша) решить невозможно, т.к. это особенность логики работы плагина W3 Total Cache, поэтому я продолжаю свои изыскания.
Не интересно, едем дальше.
По началу я отнесся к нему крайне скептически, очередной «миллион-в-одном-плагин» с кучей «свистелок», но он смог меня удивить.
Человеческая настройка исключения GET-параметров из URL-адресов, которая работает без «колхоза», возможность работы без mod_rewrite (что позволяет исполнять кастомную PHP-логику), умное автокеширование, инструменты оптимизации контента (html/js/css minify, lazy loading, генерация WebP-изображений). И это чудо работает без танцев с бубном.
Правда, на практике всё оказалось не столь радужно. О недостатках ниже.
После установки и активации плагина нас встречает вот такое меню:
Настройка Swift performance
Нажимаем "Manual configuration" и попадаем в консоль Swift perfomance, где сразу же нажимаем "Advanced view":
Настройка Swift perfomance
Настройка Swift perfomance
Настройка Swift perfomance
Нажимаем «Save changes». На этом настройка плагина закончена.
Забегая вперед, WP Fastest Cache вернул меня обратно к «колхозу». Но несмотря на это, на сегодня он попал в мои фавориты.
Настройка WP Fastest Cache
Кстати, после того как мы нажмем на «Автоматическая предварительная генерация кэша всего сайта», появится поп-ап, в котором необходимо указать следующие настройки.
Настройка WP Fastest Cache
Вот оно. Плагин, который не требует кучи параметров и просто работает. Плагин обходит сайт 1 раз в 5 минут (изменить в настройках время невозможно, но разработчики предусмотрели такую возможность через редактирование файла wp-config.php). Плагин кеширует указанное кол-во страниц (не более 12 шт. за раз, но с помощью wp-config.php можно указать любое количество). Пользователям отдаются кешированные файлы вне зависимости от их давности, а плагин в фоне (если установлена галочка «Restart After Completed») будет непрерывно обходить весь сайт для обновления файлов кеша.
Но почему я написал, что этот плагин вернул меня к «колхозу»?
Во-первых. Не довели разработчики до ума функционал игнорирования GET-параметров. UTM-метки и gclid работают без проблем - закешированная версия страницы загружается быстро. Но, к сожалению, разработчики не знают про Яндекс, и наличие метки yclid всё ломает, а страницы с такой меткой грузятся медленно. Раз уж мы начали с «колхоза», «колхозом» и закончим.
Доработка WP Fastest Cache
после чего по тому же самому принципу добавляем недостающие GET-параметры, такие как yclid.
В-вторых, WP Fastest Cache работает исключительно с помощью mod_rewrite и выполнить свой PHP-код в момент конкретной загрузки страницы посетителем нельзя. Но и это решается с помощью доработки.
Открываем в корневой директории файл .htaccess и дописываем в начало следующий код:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{HTTP:Cookie} !PHPSESSID
RewriteCond %{REQUEST_URI} !(\/){2}$
RewriteCond %{REQUEST_URI} \/$
RewriteCond %{QUERY_STRING} !.+
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/all/$1/index.html -f
RewriteRule ^(.*) "lkdm-cache.php?$1" [L]
</IfModule>
Что тут написано? Мы проверяем, что запрос был совершен без POST-параметров (т.е. это не отправка какой-то формы, логику работы которой мы не хотим нарушать), а также у пользователя отсутствовала кука PHPSESSID, отвечающая за хранение информации о сессии пользователя. В этом случае мы проверяем существует ли кеш-файл для страницы, которую пользователь пытается открыть, если да, то мы отдаем пользователю файл lkdm-cache.php с GET-запросом пользователя (полный URL-адрес) и останавливаем исполнение условий, описанных в .htaccess. В иных случаях ничего не делаем, и обработкой запроса занимаются правила WP Fastest Cache, описанные ниже в файле .htaccess. При этом, если кеш-копии файла нет, то мы ничего не делаем, наш код будет выполнен уже из корневого index.php.
Теперь нам нужно исполнить свой код. Для этого создаем файл lkdm-cache.php в корневой директории WordPress, указываем в нём тот код, который нам необходимо исполнить, а после этого пишем следующее, чтобы отдать пользователю кеш-копию страницы:
echo file_get_contents("wp-content/cache/all".$_SERVER['REQUEST_URI']."index.html");
В заключение скажу, что у всех плагинов находятся свои проблемы. Мирится с ними, не замечать или дорабатывать решает каждый сам. Полное заключение по плагинам и свои рекомендации я даю в первой части статьи. Здесь же дополню, что убедился, что даже «платность» плагина не гарантирует его качественную работу.
Напомню, что я определял для себя следующие требования к плагинам:
- Автокэширование
- Умение исключать GET-параметры и рекламные метки при кешировании
- Возможность использования PHP-функций на сайте
WP Super Cache
На сегодняшний день - это самый популярный плагин для кеширования WordPress. Его я выбрал в самом начале своих потуг в оптимизации WordPress. В процессе эксплуатации выявлялись разные «косяки» в его работе, и я периодически правил настройки, чтобы подобрать оптимальные. На текущий момент у тех сайтов, где я использую этот плагин, настройки выглядят следующим образом:Почему именно так? И почему многие настройки отличаются от рекомендованных разработчиком и рекомендаций со StackOverflow.
- Метод доставки кеша: «Простой». Эта настройка отвечает за то, кто будет обрабатывать доставку кеша. При простом методе этим будет заниматься сам WordPress с помощью PHP, а при режиме «Эксперт» все правила будут записаны в файл .htaccess, и при попытке зайти на страницу, Apache отдаст уже готовый HTML-файл, если он существует. Действительно, на цифрах второй способ работает процентов на 10-20% быстрее. Но это, если сравнивать доставку с помощью PHP (положим, TTFB: 80 мс) и доставку с помощью mod_rewrite (положим, TTFB: 60 мс). Если же сравнивать с загрузкой страницы без применения кеширования (положим, TTFB: 6 000 мс) - разница получается не столь велика. При этом, выбрав первый («простой») способ доставки кеша, код, который мы можем разместить в корневом index.php, будет исполнен. Это позволит нам реализовать свой кастомный трекинг и другую нестандартную логику. Если же нет необходимости в исполнении каких-либо PHP-скриптов на сайте, то нужно выбирать вторую настройку «Эксперт».
- Отключить кеширование для авторизованных пользователей. (Рекомендовано). Это позволит редакторам и контент-менеджерам, которые работают с сайтом регулярно, не нажимать "Удалить весь кеш", чтобы посмотреть внесенные ими изменения на страницах.
- Отключить «Сжимать файлы кэша чтобы ускорить работу (Рекомендовано)». WP Super Cache создает 3 файла: HTML-копию страницы, GZIP-архив с этой страницей (чтобы браузер мог быстрее её получить, распаковать локально на ПК пользователя и быстрее её отобразить), а также php-файл, содержащий тот же самый HTML в случае, если кеш был создан не автоматически. Именно последний php-файл и будет отдаваться пользователям, пришедшим по рекламе, при этом для PHP-файла GZIP-архив не создается. Если же мы хотим, чтобы абсолютно всем пользователям (включая привлеченных с помощью рекламы) страница отдавалась в сжатом виде, то это лучше реализовать с помощью конфига Apache. В этом случае веб-сервер самостоятельно будет сжимать с помощью GZIP любую страницу вне зависимости от типа кеширования и в случае, если кеш-файл создан вообще не был. С помощью этой настройки мы просто сэкономим место на хостинге, которое выделяется под хранение GZIP-архивов с кешем.
- Авто перестройка кэша. Гости блога увидят устаревшие версии страниц кэша пока новые будут генерироваться. (Рекомендовано). Эта настройка позволит отдавать всем пользователям всегда закешированные страницы, даже если срок жизни кеша уже истёк (в то время, пока новый кеш только создается).
- Отключить "Дополнительная сверка кэша (очень редко может нарушить работу кэширования). (Рекомендовано)". Если функция будет включена, наша кастомная логика из index.php будет постоянно ломать кеш, и он будет постоянно пересоздаваться, принуждая пользователей видеть долгую загрузку.
- Отключить "Создать список страниц в кэше (выводится на этой странице)". Нам это не нужно, список страниц всегда можно обновить и посмотреть в разделе «Состояние кеша».
Отключаем таймаут кеширования. Позже мы включим автокеширование, которое не позволит очищать автоматически созданные файлы, при этом созданные кеш-файлы по заходам пользователей из рекламы будут удаляться по таймауту. Но нам это не нужно, эти файлы будут удалены при следующем запуске автокеширования, а если мы укажем таймаут меньше, чем интервал запуска автокеширования - они попросту удаляться раньше, чем нужно. Поэтому устанавливаем значение: "0", при этом не стоит переживать за накопление мусора, при запуске автокеширования ВЕСЬ мусор будет удален.
Далее переходим на вкладку «Общий кеш», где реализуем автокеширование.
Нужно проставить все галки, а также подобрать оптимальный период обновления кеша для настраиваемого сайта.
Не стоит указывать слишком большой промежуток обновления кеша, чтобы при публикации контента, который доступен на нескольких страницах, не попасть в ситуацию, когда была опубликована новость или важный пресс-релиз, а на сайте эта публикация появляется только спустя сутки.
Да, WP Super Cache самостоятельно обновит кеш страницы при внесении в неё изменений, НО он не будет обновлять другие страницы, где может присутствовать эта запись (например, на главной, в подвале или в сайдбаре).
Слишком маленький промежуток устанавливать тоже не стоит, т.к. при запуске автокеширования будут удалены все кеш-файлы, которые были созданы, в том числе неавтоматическим способом (например, при переходе из рекламы), и пользователи, заходя на эти страницы, будут опять видеть медленную загрузку.
В общем, если на сайте активно публикуются новости или статьи, стоит указать промежуток от 1 до 2 часов. Если же сайт по большей части статичный, и на нём редко что-либо публикуется или редактируется, спокойно можно выставить интервал в 24 часа.
Также полезно будет включить галку у параметра «Сообщения о статусе кэша» на вкладке «Обслуживание», для того чтобы периодически поглядывать, когда фактически был создан кеш той или иной страницы, не отвалилось ли кеширование в принципе, нет ли проблем с автоматическим кешированием.
На этом настройка плагина завершена.
Проблемы WP Super Cache
Единственная (но критичная) проблема WP Super Cache заключается в том, что он не умеет вычленять из URL необходимые GET-параметры, и все страницы с UTM-метками и прочими аналитическими параметрами считает за уникальные.Разработчики плагина как будто бы знали о такой проблеме, потому что предусмотрели настройку «Не кешировать страницы с параметрами GET (?x=y в конце URL)». Тем не менее, она ничего не даёт, кроме экономии места на диске, потому что кеш не будет создаваться для страниц с GET-параметрами.
Единственный способ избежать этой проблемы - это «колхозить» плагин. Колхоз и допилы чужих решений - это то, за что я проклинаю всех разработчиков, потому что так делать нельзя (как минимум, после обновления плагина - все твои изменения будут отменены).
Ничего умнее я не смог придумать, как добавить в файл wp-content/plugins/wp-super-cache/wp-cache-phase1.php следующий код:
function removeGetParameter($url, $varname) {
return preg_replace('#\\?$#', '', preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','$1',$url));
}
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_source");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_medium");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_campaign");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_content");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "utm_term");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "gclid");
$wp_cache_request_uri = removeGetParameter($wp_cache_request_uri, "yclid");
после строчки $wp_cache_request_uri
Это позволяет указать плагину на то, какую страницу мы хотим достать из кеша, при этом не перенаправляя никуда пользователя (в адресной строке UTM-метки у пользователя останутся).
В итоге, проблема устранена, но не до конца. Даже если страница https://www.site.com/landing-page/ была ранее уже закеширована, при попытке зайти по ссылке https://www.site.com/landing-page/?...o-buy-something&yclid=93473892748392743473829 рядом создается еще один файл кеша (естественно страница грузится медленно). В разделе «Статистика кеша» на странице плагина мы увидим 2 идентичных элемента: https://www.site.com/landing-page/ в разделе "WP Super Cached Files" и точно такую же https://www.site.com/landing-page/ в разделе "WP Fresh Cached Files". Тем не менее, до момента истечения срока жизни кеша, при попытке обратиться с любым набором из описанных GET-параметров, который мы «приколхозили» с любым их значением (например, https://www.site.com/landing-page/?gclid=666), пользователю уже будет отдаваться кешированная версия (т.е. страница загрузится быстро).
Таким образом, если реклама ведется только на одну страницу сайта, а срок жизни кеша 1 час, то раз в час один пользователь будет грузить страницу медленно (пока создается кеш), при этом все остальные пользователи будут получать страницу быстро, ровно, как и те люди, которые заходят на сайт из поиска или по другим источникам без GET-параметров.
Ситуация стала значительно лучше, но до сих пор не идеальна. Представим, что реклама ведется на 100 страниц, реклама очень сильно таргетированная и с урезанными бюджетами. Так что не факт, что в час хотя бы один человек зайдет на ту или иную страницу (по рекламе). В этом случае профит не столь очевидный. При таком раскладе каждый привлеченный по рекламе человек будет долго ждать пока страница будет загружена.
Перелопатив тысячи строк кода, я так и не нашел способ это победить. Поэтому для себя, пока что, я нашел очень «костыльный», но всё же работающий способ решить эту проблему:
- Пишем PHP-скрипт, который поштучно обходит файл sitemap.xml и дёргает за раз по 10 ссылок (поочередно)
- Добавляем к каждой ссылке «/?utm_source=test» и с помощью file_get_contents «открываем» эти страницы
- Вешаем этот скрипт на CRON с запуском каждую минуту
Да, в лоб, но это работает! Если кто-то найдет более элегантный способ подружить WP Super Cache с GET-параметрами - приглашаю в комментарии.
WP Rocket
В попытках найти более элегантный способ для реализации кеширования с GET-параметрами, я решил попробовать другой плагин - WP Rocket. И это полный провал. Несмотря на то, что плагин распространяется исключительно платно (по подписке), имеет красивый интерфейс и кучу настроек - все они бесполезны!Во-первых, возможности выбора метода доставки кеша (mod_rewrite или PHP) нет, он работает исключительно через mod_rewrite, поэтому реализовать кастомный трекинг (как и любую другю PHP-логику) невозможно.
Во-вторых, автокеширование даже сравнительно небольшого сайта (~100 страниц) убивает напрочь сервер, на котором он крутится (скорее всего WP Rocket пытается осуществить обход всех страниц разом).
В-третьих, уже созданный кеш на половине страниц отваливается буквально через пару минут после его создания по неизвестной причине.
В общем, я даже не стал тратить время на доработки этого плагина.
W3 Total Cache
Следующим на очереди у меня был W3 Total Cache. Он хорошо себя показал, и имеет право на жизнь. Он имеет настройку, которая позволяет игнорировать указанные GET-параметры, и это работает без «костылей», как с WP Super Cache. Также W3 Total Cache имеет возможность работать через PHP (выбрав в разделе "Page Cache" настройку хранилища "Disk: Basic", код, размещенный в корневом index.php, будет исполнен, а скорость загрузки закешированных страниц будет высокая, сопоставимая с результатами WP Super Cache). В целом, функционал W3 Total Cache значительно превосходит WP Super Cache. Помимо множества вариантов более сложного кеширования (Memcached, APC, Zend OPcache, Redis), он из коробки умеет объединять и сжимать HTML, CSS и JS, а также выполнять Lazy Loading изображений.Тем не менее для меня критичными оказались 2 проблемы:
- По неизвестной причине страницы, периодически, грузятся очень долго. При этом на странице присутствует комментарий, что она была давно закеширована и, по логике, должна отдаваться быстро, но страница грузится долго. Чаще всего такое поведение наблюдается на втором клике визита (вне зависимости от того, какую страницу открыть). Кеш таких страниц в момент долгой загрузки не обновляется, т.е. после перезагрузки страницы, или, при открытии её с другого устройства, комментарий, содержащий информацию о времени кеширования, остается неизменным. Решается эта проблема переключением обработчика на mod_rewrite (в настройках Page Cahe эта опция называется "Disk: Enhanced"). Но в моём случае это неприменимо, т.к. мне требуется выполнение PHP-кода при посещении страниц.
- Вторая очень болезненная проблема - это процесс обновления кеша. W3 Total Cache конечно имеет функцию пребилда, т.е. он автоматически с заданным интервалом обходит сайт согласно sitemap.xml для создания кеш-файлов. При этом обход он осуществляет непрерывно, но пересоздает кеш-файлы лишь в тот момент времени, когда кеш уже устарел. В итоге получается следующая ситуация - в момент, когда время жизни кеша истекло, W3 Total Cache не успевает быстро обойти весь сайт, чтобы обновить кеш-файлы, и когда пользователь пытается зайти на страницу, с большой вероятностью она окажется с просроченным кешем и будет грузиться медленно. Ротация обхода тоже вряд ли совпадет с датами истечения кеша страниц, потому что обход запускается не в какой-то определенный момент времени, а работает непрерывно. И если страница была закеширована в 21:00, то далеко не факт, что после истечения срока жизни кеша (например, 1 час) эта страница попадет в обход ровно в 22:00.
- Сайт 100 страниц
- Время жизни кеша: 1 час
- TTFB без кеширования: 5-6 сек (5 000 – 6 000 мс)
- Обход: 1 раз в минуту по 10 страниц (за указанный промежуток времени больше 10 страниц при таких характеристиках лучше не обходить, т.к. если страницы не будут успевать кешироваться, то будет забиваться Cron и расти нагрузка на сервер. Меньше 1 раза в минуту указать нельзя, т.к. минута - это минимальный интервал Cron-а WordPress).
Увеличивать время жизни кеша не хочется. Да, при обновлении страниц или новостей кеш для них автоматически будет обновлен, но на других страницах, куда могут быть подгружены эти записи, например, на главную, кеш обновлен не будет, а соответственно, добавленная или измененная запись там не появятся ровно до тех пор, пока не истечет время жизни предыдущего кеша.
Тем не менее в случае, если нет желания дорабатывать WP Super Cache, то W3 Total Cache вполне себе альтернатива. Также W3 Total Cache отлично подойдет для статичных сайтов, где можно обновлять кеш раз в сутки - запустил один раз ночью, и пусть он всё обновляет пока на сайте трафика мало. Либо вообще не использовать функцию автокеширования и обновлять кеш вручную при изменении сайта.
Настройка W3 Total Cache
После установки и активации плагина, нас встречает "Мастер настройки". Для каждого типа кеширования он проведет наглядные тесты и предложит на выбор разные параметры кеширования.- На вкладке "Page Cache" выбираем "Диск: базовое", если хотим использовать кастомную PHP-логику. Если наличие такой возможности не критично, то выбираем "Диск: расширенное", в этом случае рулить доставкой кеша будет mod_rewrite, а скорость загрузки страниц будет немного выше.
- На вкладке "Кеш БД" выбираем "Отсутствует", т.к. у нас уже есть закешированные копии HTML-страниц. Кеширование БД нам потребуется только в том случае, если по какой-то причине кеширование страниц (Page Cache) отключено.
- На вкладке "Объектное кеширование" выбираем "Отсутствует", т.к. у нас уже есть закешированные копии HTML-страниц. Кеширование объектов нам потребуется только в том случае, если по какой-то причине кеширование страниц (Page Cache) отключено.
- На вкладке "Browser Cache" выбираем "Включено", это позволит сохранить на непродолжительное время копию страницы сайта в браузере пользователя. И, если он повторно попытается зайти на эту страницу, она мгновенно будет загружена браузером из локального хранилища устройства пользователя.
- "Lazy Load изображений" сейчас мы не включаем, это уже относится к оптимизации контента на сайте. Способы оптимизации HTML, JS, CSS и изображений можно рассмотреть в отдельной статье.
Включаем автокеширование ("Автоматическая настройка кеша страницы"), указываем интервал обновления (минимум 60 секунд, т.к. WP Cron не умеет работать быстрее), указываем кол-во страниц в интервале - выбираем в зависимости от скорости загрузки страниц без применения кеширования (если без кеширующего плагина в среднем TTFB страниц ~5 сек., то стоит указать кол-во не более 12, чтобы не нагружать лишний раз сервер). Также необходимо указать путь к Sitemap.XML, на основе которого будет осуществляться обход сайта. Рекомендую использовать для построения Sitemap.XML плагин "Yoast SEO", т.к. для интеграции с Yoast SEO у W3 Total Cache есть отдельное расширение, а это значит, что сайтпамы, сгенерированные Yoast SEO будут поглощаться плагином W3 Total Cache без каких-либо ошибок.
Чтобы отключить автокеширование у плагина W3 Total Cache достаточно поставить 0 в интервале обновления.
Далее спускаемся к разделу "Advanced":
В блоке "Принятые строки запроса" указываем те GET-параметры URL-адресов, которые мы не хотим кешировать отдельно. Также укажем значения "Максимальное время жизни кэшированых объектов" и "Период удаления устаревшего кэша" в зависимости от того как часто мы хотим обновлять кеш. Нажимаем "Сохранить настройки и очистить кэш". На этом настройка плагина завершена.
Выше я уже писал о том, что периодически, несмотря на то, что кеш для определенных страниц уже создан, они все равно грузятся медленно. Частично исправить эту проблему поможет включение PHP-расширения "Zend Opcache" на сервере с сайтом.
Тем не менее вторую проблему (долгая загрузка страниц в период обновления кеша) решить невозможно, т.к. это особенность логики работы плагина W3 Total Cache, поэтому я продолжаю свои изыскания.
LiteSpeed Cache
Еще один популярный плагин для кеширования WordPress. Как оказалось, это попросту рекламный инструмент, вынуждающий пользователей использовать веб-сервер LiteSpeed вместо Apache или nginx, обещая при этом космическую скорость работы сайта (несмотря на то, что половина шаблонов и плагинов не будут работать на LiteSpeed, т.к. не оптимизированы под него). Что вообще за зверь этот LiteSpeed лучше всего продемонстрируют комментарии на Хабре: https://qna.habr.com/q/5543Не интересно, едем дальше.
Swift performance
Очередной плагин, распространяющийся исключительно по подписке.По началу я отнесся к нему крайне скептически, очередной «миллион-в-одном-плагин» с кучей «свистелок», но он смог меня удивить.
Человеческая настройка исключения GET-параметров из URL-адресов, которая работает без «колхоза», возможность работы без mod_rewrite (что позволяет исполнять кастомную PHP-логику), умное автокеширование, инструменты оптимизации контента (html/js/css minify, lazy loading, генерация WebP-изображений). И это чудо работает без танцев с бубном.
Правда, на практике всё оказалось не столь радужно. О недостатках ниже.
Настройка Swift perfomance
Параметров для настройки у Swift perfomance огромное множество. Поэтому будет проще не перечислять их все, а указать лишь те, которые отличаются от дефолтных.После установки и активации плагина нас встречает вот такое меню:
Нажимаем "Manual configuration" и попадаем в консоль Swift perfomance, где сразу же нажимаем "Advanced view":
- Раздел Media -> Images отключаем функции "Generate WebP" и "Lazyload Images", так как, повторюсь, мы сейчас работаем именно с кешированием, а не с оптимизацией контента на сайте. К тому же этот функционал требует тестирования, т.к. не везде он работает адекватно и даёт ощутимый прирост в производительности.
- Раздел Optimization -> General отключаем "Fix Invalid HTML" (всё по той же причине, что и выше).
- Раздел Caching -> General оставляем значение параметра "Caching Mode" = "Disk Cache with PHP", чтобы иметь возможность выполнять свои PHP-скрипты в корневом index.php или же выбираем "Disk Cache with Rewrites", чтобы слегка увеличить скорость загрузки сайта.
- Раздел Caching -> General устанавливаем значение параметра "Cache Expiry Mode" = "Action based mode" чтобы кеш обновлялся не по таймеру, а только при внесении изменений.
- Раздел Caching -> Tweaks в разделе "Ignore GET Params" указываем перечень наших GET-параметров для исключения из обработки URL при кешировании и отдачи кеш-файлов.
- Раздел Caching -> Warmup включаем "Prebuild Cache Automatically", как раз для автокеширования, скорость выбираем согласно рекомендациям (Moderate для shared-хостинга, Multi thread - если сайт крутится на своей VDS), а также включаем опцию "Discover New Pages", чтобы плагин искал и кешировал новые страницы автоматически.
Нажимаем «Save changes». На этом настройка плагина закончена.
Недостатки Swift perfomance
- Он не умеет в кириллицу. Swift perfomance создает кеш ровно по тем адресам, которые имеют страницы сайта, т.е. если у нас URL страницы выглядит как https://example.com/контакты, он не будет переводить "контакты" в URL-encoded для создания кеша. Но браузер будет обращаться именно к https://example.com/контакты, поэтому страницы, содержащие кириллицу, будут загружаться всегда медленно. Мелочь, но неприятно.
- Скорость загрузки закешированных страниц с помощью Swift Perfomance всё же в 2-3 раза медленней, чем у WP Super Cache или у W3 Total Cache. Опять же, это не столь критично, когда при использовании кеширующего плагина скорость загрузки страницы упала с 8 000 мс до 300 мс, а не до 100 мс. Ведь не стоит забывать, что в этот момент пользователь всё равно не может пользоваться сайтом, т.к. страница должна отрендериться в браузере, должны загрузиться статичные файлы (css, js, картинки), а это явно не 100 и даже не 300 миллисекунд (если, конечно, сайт - это не черный текст на белом фоне).
- Критичной стала проблема в работе «умного» кеширования в режиме «Action based mode». Разработчики заявляют, что при внесении изменений на сайте, запускается процесс обхода всех страниц сайта, при котором создаются новые кеш-копии файлов, а посетителям сайта продолжают отдаваться старые, пока новые не создадутся. В теории сайт всегда должен работать быстро, кеш перестраиваться максимально оперативно после обновления какой-либо информации на сайте, при этом нагрузка на сервер должна быть минимальной, т.к. процесс кеширования не происходит ровно до того момента, пока на сайте не были внесены изменения. По началу так и работает, но в какой-то момент всё ломается. На практике это «умное» автокеширование работает нестабильно. В какой-то момент созданные ранее кеш-файлы просто пропадают, плагин их удаляет или происходит какой-то рассинхрон, хотя новые копии под них ещё не были созданы, и сайт остаётся без какого-либо кеширования. Приходится запускать переобход вручную, а это ведёт к сильной нагрузке на сервер.
Если же выбрать классический вариант обновления кеша (по таймауту) - "Time based mode" - проявятся все те же проблемы как у WP Rocket или W3 Total Cache - то отвалится автокеширование, то кеш-файлы будут удалены буквально через пару минут после их генерации. В общем, пользоваться Time based mode я не смог.
Когда мы вручную обновляем весь кеш сайта, далеко не все страницы работают быстро. Через несколько минут после ручного запуска переобхода сайта, часть страниц уже имеют новый кеш (работают быстро), часть страниц еще отдаются со старым кешем (видим, что свежая новость в сайдбарах на этих страницах еще не появилась), но часть страниц (причем, немалая) грузится ужасно долго (8 – 12 сек. против 3-4 сек. без использования кеширования вообще).
WP Fastest Cache
WP Fastest Cache — это еще один популярный плагин для кеширования WordPress.Забегая вперед, WP Fastest Cache вернул меня обратно к «колхозу». Но несмотря на это, на сегодня он попал в мои фавориты.
Настройка WP Fastest Cache
- Скачиваем и активируем плагин
- Ставим три галки как показано на скриншоте
- Готово
Кстати, после того как мы нажмем на «Автоматическая предварительная генерация кэша всего сайта», появится поп-ап, в котором необходимо указать следующие настройки.
Вот оно. Плагин, который не требует кучи параметров и просто работает. Плагин обходит сайт 1 раз в 5 минут (изменить в настройках время невозможно, но разработчики предусмотрели такую возможность через редактирование файла wp-config.php). Плагин кеширует указанное кол-во страниц (не более 12 шт. за раз, но с помощью wp-config.php можно указать любое количество). Пользователям отдаются кешированные файлы вне зависимости от их давности, а плагин в фоне (если установлена галочка «Restart After Completed») будет непрерывно обходить весь сайт для обновления файлов кеша.
Но почему я написал, что этот плагин вернул меня к «колхозу»?
Во-первых. Не довели разработчики до ума функционал игнорирования GET-параметров. UTM-метки и gclid работают без проблем - закешированная версия страницы загружается быстро. Но, к сожалению, разработчики не знают про Яндекс, и наличие метки yclid всё ломает, а страницы с такой меткой грузятся медленно. Раз уж мы начали с «колхоза», «колхозом» и закончим.
после чего по тому же самому принципу добавляем недостающие GET-параметры, такие как yclid.
В-вторых, WP Fastest Cache работает исключительно с помощью mod_rewrite и выполнить свой PHP-код в момент конкретной загрузки страницы посетителем нельзя. Но и это решается с помощью доработки.
Открываем в корневой директории файл .htaccess и дописываем в начало следующий код:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{HTTP:Cookie} !PHPSESSID
RewriteCond %{REQUEST_URI} !(\/){2}$
RewriteCond %{REQUEST_URI} \/$
RewriteCond %{QUERY_STRING} !.+
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/all/$1/index.html -f
RewriteRule ^(.*) "lkdm-cache.php?$1" [L]
</IfModule>
Что тут написано? Мы проверяем, что запрос был совершен без POST-параметров (т.е. это не отправка какой-то формы, логику работы которой мы не хотим нарушать), а также у пользователя отсутствовала кука PHPSESSID, отвечающая за хранение информации о сессии пользователя. В этом случае мы проверяем существует ли кеш-файл для страницы, которую пользователь пытается открыть, если да, то мы отдаем пользователю файл lkdm-cache.php с GET-запросом пользователя (полный URL-адрес) и останавливаем исполнение условий, описанных в .htaccess. В иных случаях ничего не делаем, и обработкой запроса занимаются правила WP Fastest Cache, описанные ниже в файле .htaccess. При этом, если кеш-копии файла нет, то мы ничего не делаем, наш код будет выполнен уже из корневого index.php.
Теперь нам нужно исполнить свой код. Для этого создаем файл lkdm-cache.php в корневой директории WordPress, указываем в нём тот код, который нам необходимо исполнить, а после этого пишем следующее, чтобы отдать пользователю кеш-копию страницы:
echo file_get_contents("wp-content/cache/all".$_SERVER['REQUEST_URI']."index.html");
Стоит обратить внимание
- После обновления плагина WP Fastest Cache всегда необходимо вносить изменения, связанные с GET-параметрами в файл /wp-content/plugins/wp-fastest-cache/inc/cache.php
- После обновления настроек плагина WP Fastest Cache всегда необходимо переносить добавленный в .htaccess код в самое начало, т.к. ровно то же самое (перенос в начало) делает плагин при обновлении настроек. Соответственно, наш код из .htaccess исполнен не будет, если он находится ниже куска кода от WP Fastest Cache.
Заключение
Сейчас на большинстве проектов я использую WP Fastest Cache со своими доработками. W3 Total Cache устанавливаю только на статичные сайты, обычно лендинги, где практически не вносятся изменения, он будет выдавать максимальную скорость загрузки. Также WP Super Cache устанавливаю периодически на сайты, если точно знаю, что на сайт не будет вестись реклама в будущем, т.к. мне он кажется самым простым в установке и настройке. WP Super Cache в этом плане был бы самым универсальным и стабильно работающим плагином, если бы разработчики предусмотрели возможность исключения части запросов из URL-адреса. Сейчас же приходится дорабатывать исходный код.В заключение скажу, что у всех плагинов находятся свои проблемы. Мирится с ними, не замечать или дорабатывать решает каждый сам. Полное заключение по плагинам и свои рекомендации я даю в первой части статьи. Здесь же дополню, что убедился, что даже «платность» плагина не гарантирует его качественную работу.
PS
Это переписанная и структурированная статья из моего телеграм-канала «digital на минималках», где я делюсь опытом в бизнесе, инструкциями, рассказываю, как удешевить свои вложения в digital, рассуждаю на небанальные темы, немного бомблю и делюсь мемчиками (осторожно, ненормативная лексика). Решил, что подобное объемное исследование будет интересно не только подписчикам моего канала.Ускорение WordPress. Тотальный разбор плагинов для кэширования. Личный опыт (часть 2)
В этой части я подробно рассмотрю принцип работы каждого плагина, о которых говорил в первой части , а также приведу код с доработками для закрытия проблем плагинов. Кратко все преимущества и...
habr.com