Оптимизация сайтов на WordPress, снижение нагрузки и защита от ботов

22.09.2023 — Обновлено

В инструкции собраны рекомендации тех. поддержки хостинга Sprinthost, которым я пользуюсь. Некоторые блоки содержат агрегированную информацию из различных тематических сайтов и форумов. Статья обновляемая, новые пункты будут добавляться и актуализироваться.

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

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

Кэширование страниц

Идеального рецепта не существует и нам необходимо разобраться в логике работы того или иного плагина и выбрать наиболее подходящее решение для каждого конкретного сайта.

WP Super Cache

На сегодняшний день — это самый популярный плагин для кэширования WordPress. Именно его я и выбрал к использованию в самом начале своих потуг в оптимизации WordPress. В процессе эксплуатации выявлялись разные косяки в его работе и я периодически правил его настройки с целью подобрать наиболее оптимальные для использования.

  • Метод доставки кеша: Простой — эта настройка отвечает за то, кто будет обрабатывать доставку кеша. При простом методе — этим будет заниматься сам WordPress с помощью PHP, при режиме «Эксперт» все правила будут записаны в файл .htaccess и при попытке зайти на страницу Apache отдаст уже готовый HTML-файл если он существуют. Действительно, на цифрах второй способ работает процентов на 10-20% быстрее. Но это, если сравнивать доставку с помощью PHP (положим, TTFB: 80 мс) и доставку с помощью mod_rewrite (положим, TTFB: 60 мс). Если же сравнивать с загрузкой страницы без применения кеширования (положим, TTFB: 6 сек) — разница получается не столь велика. При этом, выбрав первый (простой) способ доставки кеша — код, который мы можем разместить в корневом index.php будет исполнен. Это позволит нам реализовать свой кастомный трекинг (ну и другую нестандартную логику, если она нужна).
  • Отключить кеширование для авторизованных пользователей. (Рекомендовано) — это позволит редакторам и контент-менеджерам, которые работают с сайтом постоянно не нажимать «Удалить весь кеш», чтобы посмотреть внесенные ими изменения на страницах.
  • Отключить «Сжимать файлы кэша чтобы ускорить работу. (Рекомендовано)» — WP Super Cache создает 3 файла: HTML-копию страницы, GZIP-архив с этой страницей (чтобы браузер мог быстрее её получить, распаковать локально на ПК пользователя и быстрее её отобразить), а также php-файл содержащий тот же самый HTML в случае, если кеш был создан не автоматически — именно он и будет отдаваться пользователям, пришедшим по рекламе, при этом для PHP-файла GZIP-архив не создается. Если же мы хотим, чтобы абсолютно всем пользователям (включая привлеченных с помощью рекламы) страница отдавалась в сжатом виде — это лучше реализовать с помощью конфига Apache. В этом случае, веб-сервер самостоятельно будет сжимать с помощью GZIP любую страницу вне зависимости от типа кеширования и в случае, если кеш-файл создан вообще не был. С помощью этой настройки мы просто сэкономим место на хостинге, которое выделяется под хранение GZIP-архивов с кешем.
  • Авто перестройка кэша. Гости блога увидят устаревшие версии страниц кэша пока новые будут генерироваться. (Рекомендовано) — эта настройка позволит отдавать всем пользователям всегда только кешированные страницы, даже если срок жизни этого кеша уже истёк (в то время пока новый кеш только создается).
  • Отключить «Дополнительная сверка кэша (очень редко может нарушить работу кэширования). (Рекомендовано)» — если функция будет включена, наша кастомная логика из index.php будет постоянно ломать кеш в этом случае, и он будет постоянно пересоздаваться, заставляя пользователей видеть долгую загрузку.
  • Отключить «Создать список страниц в кэше (выводится на этой странице)» — нам это не нужно, список страниц всегда можно обновить и посмотреть в разделе «Состояние кеша».

Отключаем таймаут кеширования. Позже мы включим автокеширование, которое не позволит очищать автоматически созданные файлы, при этом созданные кеш-файлы по заходам пользователей из рекламы будут удаляться по таймауту. На нам это нужно, эти файлы будут удалены при следующем запуске автокеширования, а если мы укажем таймаут меньше, чем интервал запуска автокеширования — они попросту удаляться раньше, чем нужно. Поэтому устанавливаем значение: «0», при этом не стоит переживать за накопления мусора — при запуске автокеширования ВЕСЬ мусор будет удален.

Далее переходим на вкладку «Общий кеш» — именно она нам позволит реализовать автокеширование.

Нужно проставить все галки, а также подобрать наиболее оптимальный период обновления кеша для настраиваемого сайта.

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

Да, WP Super Cache самостоятельно обновит кеш страницы при внесении в неё изменений, НО он не будет обновлять те страницы, где может также присутствовать эта запись (например на главной в подвале, или в сайдбаре у всех новостей).

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

В общем, если на сайте активно публикуются новости или статьи — стоит указать промежуток от 1 до 2 часов. Если же сайт по большей части статичный, и на нём редко что-либо публикуется или редактируется — спокойно можно выставить интервал в 24 часа.

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

На этом настройка плагина завершена.

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 проблемы:

  1. По неведомой для меня причине, периодически страницы очень долго грузятся. При этом, на странице присутствует комментарий, что она была довольно давно закеширована (поэтому по идее отдаваться должна быстро, но этого не происходит). Чаще всего такое поведение замечается именно на втором клике визита (вне зависимости от того, какую страницу ты пытаешься открыть). Кеш таких страниц, в момент долгой загрузки при этом не обновляется — т.е. после перезагрузки такой страницы (или когда пытаемся открыть её с другого устройства) — комментарий содержащий информацию о времени кеширования остается неизменным. Решается эта проблема переключением обработчика на mod_rewrite (в настройках Page Cahe эта опция называется «Disk: Enhanced»). Но в моём случае это не применимо, т.к. нам требуется выполнение PHP-кода при посещении страниц.
  2. Вторая очень болезненная проблема — это процесс обновления кеша. Да, W3 Total Cache имеет функцию пребилда — т.е. он автоматически в заданный с заданным интервалом обходит сайт согласно sitemap.xml, с целью создать кеш-файлы. При этом, обход он осуществляет непрерывно, но пересоздает кеш-файлы лишь в тот момент времени, когда кеш уже устарел. В итоге получается следующая ситуация — в момент, когда время жизни кеша истекло даже не небольших сайтах, W3 Total Cache не успевает быстро обойти весь сайт, чтобы обновить кеш-файлы. При этом, они уже истекли, и когда пользователь пытается зайти на ту или иную страницу — с крайне высокой долей вероятности она окажется с просроченным кешем, поэтому кеш для этой страницы будет создаваться заново, а такие страницы будут грузиться медленно. Ротация обхода тоже вряд ли совпадет с датами истечения кеша страниц, потому что обход запускается не в какой-то определенный момент времени, а работает непрерывно. И если страница была закеширована в 21:00, то далеко не факт, что после истечения срока жизни кеша (например, 1 час) эта старница попадет в обход именно в 22:00.

    В итоге имеем ситуацию:
    — Сайт 100 страниц
    — Время жизни кеша: 1 час
    — TTFB (по сути, время генерации страницы) без кеширования: 5-6 сек.
    — Обход: 1 раз в минуту по 10 страниц (больше 10 страниц при таких характеристиках лучше не обходить за указанный промежуток времени, если страницы не будут успевать кешироваться — будет забиваться Cron и расти нагрузка на сервер. Меньше 1 раза в минуту интервал указать нельзя — т.к. минута — это минимальный интервал Cron-а WordPress).

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

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

Тем не менее, в случае, если у тебя нет желания «колхозить» 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 и изображений мы рассмотрим в отдельной статье.

Далее переходим в админке в раздел «Perfomance» — «Page cache»

Включаем автокеширование («Автоматическая настройка кеша страницы»), указываем интервал обновления (минимум 60 секунд, т.к. WP Cron не умеет работать быстрее), указываем кол-во страниц в интервале — выбираем в зависимости от скорости загрузки страниц без применения кеширования (если без кеширующего плагина в среднем TTFB страниц ~5 сек., то стоит указать кол-во не более 12, чтобы не нагружать лишний раз сервер). Также, необходимо указать путь к Sitemap.XML на основе которого будет осуществляться обход сайта. Рекомендую использовать для построения Sitemap.XML плагин «Yoast SEO», т.к. для интеграции с Yoast SEO у W3 Totack Cache есть отдельно расширение, а это значит, что сайтпамы, сгенерированные Yoast SEO явно будут поглощаться плагином W3 Total Cache без каких-либо ошибок.

Далее спускаемся к разделу «Advanced»:

В блоке «Принятые строки запроса» указываем те GET-параметры URL-адресов, которые мы не хотим кешировать отдельно. Также, укажем значения «Максимальное время жизни кэшированых объектов» и «Период удаления устаревшего кэша» в зависимости от того как часто мы хотим обновлять кеш. Нажимаем «Сохранить настройки и очистить кэш» — на этом настройка плагина завершена.

Выше я уже писал о том, что периодически, не смотря на то, что кеш для определенных страниц уже создан — они все равно грузятся медленно. Частично исправить эту проблему поможет включение PHP-расширения «Zend Opcache» на сервере с сайтом.

Тем не менее, вторую проблему (долгая загрузка страниц в период обновления кеша) решить невозможно, т.к. это особенность логики работы плагина W3 Total Cache, поэтому я продолжаю свои изыскания.

Отключите HeartBeat API — самый ресурсоемкий процесс в WordPress

Комментарий тех. поддержки: «У сайта большое количество запросов к admin-ajax.php».

Запросы к скрипту admin-ajax.php при работе в административной панели, как правило, указывают на активную работу инструмента WordPress HeartBeat API. Эти процессы являются самым ресурсоемким механизмом WordPress из стандартных.

HeartBeat API это процесс, который организует одновременную работу нескольких пользователей в административной части сайта.

Если у сайта один администратор, отключите эту функцию. Поможет в этом плагин Heartbeat Control. Установите и активируйте его в разделе «Плагины» административной части и перейдите в «Настройки» → «Heartbeat Control Settings».

Отключите HeartBeat API полностью, выбрав опцию «Disable Heartbeat» для всех доступных локаций сайта

Код ответа 404 передавать в обход скриптов CMS

У WordPress такоие запросы обрабатываются долго, с участием скриптов CMS, и на генерацию страницы с сообщением об ошибке 404 (не найдено) затрачивается некоторое количество ресурсов.

Разместите недостающие файлы или удалите ссылки на них в скриптах и базе данных сайта.

Альтернативно, настройте сайт так, чтобы код ответа 404 передавался в обход скриптов CMS. Для этого добавьте в .htaccess из корневой директории сайта директивы:

RewriteCond %{REQUEST_URI} \.(jpeg|jpg|png|gif|css|js)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* - [R=404]

Оптимизация работы работа WP-cron

WP-cron — встроенный в CMS планировщик задач. Его активирует обращение к любой странице сайта. Если задание должно выполниться в 10:30, но в этот момент посетителей на сайте нет, его запуск отложится. Оно выполнится, когда на сайт кто-нибудь перейдет.

Такая работа планировщика вызывает всплеск потребления ресурсов, чтобы этого не происходило, перенесите выполнение заданий WP-cron на планировщик от хостинга.

Для отключения добавьте в файл wp-config.php (он расположен в корневой директории сайта) сразу после открывающего тега PHP строку с текстом:

define('DISABLE_WP_CRON', true);

Далее необходимо перейти в планировщик cron на хостинге и настроить задание, например:

1 * * * * /usr/local/bin/wget -q -O /dev/null http://domain.ru/wp-cron.php

Оно будет выполняться каждую первую минуту часа.

Если у вас несколько сайтов, распределяйте задания так, чтобы они не выполнялись в одну и ту же минуту.

SeoKardinal
Мы будем рады и вашему мнению

Оставьте отзыв

SeoKardinal
Logo