Перейти к содержимому
Почта Личный кабинет Выбрать тариф

Как ускорить WordPress: что дает наибольший эффект (замеры на стенде)

Как ускорить WordPress: что дает наибольший эффект (замеры на стенде)

Сильнее всего WordPress ускоряет кеш страниц: на нашем тестовом стенде время до первого байта (TTFB) упало с 41 до 0,3 мс, а сервер стал отдавать не 44, а больше 14 тысяч страниц в секунду. Вторым по эффекту шагом стал OPcache (190 мс без него и 41 мс с ним), третьим поиск тормозящего плагина: его имитация добавила к каждому запросу около 265 мс. Дальше по убыванию влияния идут воркеры PHP-FPM, сжатие, изображения, object cache и только в конце чистка autoload: 3 МБ автозагружаемых опций добавили всего около 4 мс.

Как мы проверяли

Тестовый стенд RichHost, октябрь 2026: изолированный контейнер 2 vCPU / 8 ГБ RAM, Ubuntu 24.04, nginx 1.24, PHP 8.3-FPM, MariaDB 10.11, WordPress 6.7.2, тема Twenty Twenty-Five, 300 сгенерированных записей. Запросы отправлялись с того же сервера (127.0.0.1), поэтому сеть и TLS в цифры не входят. TTFB измеряли как медиану и 90-й перцентиль (p90) из 40 запросов curl после трех прогревочных, пропускную способность через ab (300 запросов по 10 одновременно), тестировали главную страницу и запись. «Тяжелый плагин»: наш mu-плагин, который делает 150 лишних SQL-запросов и 250 мс ждет внешний API. Меняли по одному фактору. Это лабораторные цифры стенда, а не показатели продакшн-серверов RichHost.

Результаты замеров

Сценарий TTFB, медиана (главная / запись) TTFB, p90 Запросов в секунду
OPcache выключен 190 / 195 мс 210 / 216 мс 9,7 / 9,8
OPcache включен 41 / 45 мс 45 / 51 мс 44,1 / 41,6
OPcache + Redis object cache* 39,7 / 39,6 мс 49,4 / 46,2 мс 47,3 / 48,4
OPcache + кеш страниц nginx 0,3 / 0,3 мс 0,4 / 0,3 мс 21 581 / 14 749
Тяжелый плагин, без кеша страниц 309 / 311 мс 325 / 323 мс 15,3 / 15,0
Тяжелый плагин + Redis object cache 306 / 306 мс 319 / 314 мс 15,3 / 15,4
Тяжелый плагин + кеш страниц 0,2 / 0,3 мс 0,3 / 0,3 мс 18 703 / 15 202
Администратор в системе (кеш в обход) 44,8 / 45,9 мс 49,6 / 56,2 мс 39,8 / 38,8
+3 МБ autoload-опций 45,4 / 45,4 мс 59,5 / 59,0 мс 42,3 / 39,3

* Строки с Redis измерены отдельной серией, где базовый вариант без object cache дал 43,7 / 46,8 мс.

Медианный TTFB WordPress на тестовом стенде: без OPcache 190 мс, с тяжелым плагином 309 мс, с OPcache 41 мс, с кешем страниц 0,3 мс
TTFB на тестовом стенде RichHost: кеш страниц убирает и работу PHP, и задержку тяжелого плагина

Из таблицы следуют два неочевидных вывода. Первый: кеш страниц не лечит медленный плагин, а прячет его от анонимных посетителей. Администратор, покупатель с корзиной WooCommerce или любой посетитель с кукой входа получает страницу в обход кеша, то есть те же 45 мс на чистом сайте и больше 300 мс с тяжелым плагином. Второй: раздутый autoload, который во многих советах стоит первым, на стенде почти не повлиял на скорость. Из чего складывается TTFB и почему работает сжатие, мы разобрали в статье TTFB, кеш и сжатие, здесь только практика.

Шаг 1. Кеш страниц

Без кеша WordPress на каждый запрос запускает PHP, выполняет 22-29 SQL-запросов (столько насчитал счетчик на главной и на странице записи) и собирает HTML заново. Кеш страниц отдает готовый HTML, поэтому TTFB снизился с 41-45 до 0,2-0,3 мс, причем одинаково и для чистого сайта, и для сайта с тяжелым плагином. На реальном сайте добавится сеть, но работа сервера почти исчезает.

На стенде мы проверили такой конфиг nginx fastcgi_cache. Он кеширует только анонимные GET-запросы и пропускает мимо кеша POST, адреса с параметрами, админку, REST API, а также посетителей с кукой входа, комментария или корзины WooCommerce:

fastcgi_cache_path /var/cache/nginx/wp levels=1:2 keys_zone=WPCACHE:64m max_size=1g inactive=60m use_temp_path=off;

server {
  # ... listen, server_name, root, index ...

  set $skip_cache 0;
  if ($request_method = POST) { set $skip_cache 1; }
  if ($query_string != "") { set $skip_cache 1; }
  if ($request_uri ~* "/wp-admin/|/wp-json/|/xmlrpc.php|wp-.*\.php|/feed/|sitemap(_index)?\.xml") { set $skip_cache 1; }
  if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash") { set $skip_cache 1; }

  location / { try_files $uri $uri/ /index.php?$args; }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_cache WPCACHE;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    fastcgi_cache_valid 200 301 10m;
    fastcgi_cache_use_stale error timeout updating http_500 http_503;
    fastcgi_cache_background_update on;
    fastcgi_cache_lock on;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    add_header X-Cache $upstream_cache_status always;
  }
}

Проверка правил (заголовок X-Cache показывает, откуда пришла страница):

$ curl -sI http://127.0.0.1:8081/post-293/ | grep X-Cache
X-Cache: MISS
$ curl -sI http://127.0.0.1:8081/post-293/ | grep X-Cache
X-Cache: HIT
$ curl -sI -b wordpress_logged_in_abc=x http://127.0.0.1:8081/post-293/ | grep X-Cache
X-Cache: BYPASS
$ curl -sI http://127.0.0.1:8081/post-293/?utm_source=x | grep X-Cache
X-Cache: BYPASS

О двух вещах стоит знать заранее. Страница хранится в кеше 10 минут (fastcgi_cache_valid), так что после правки записи анонимные посетители могут видеть старую версию до 10 минут, если не настроить очистку кеша, например плагином Nginx Helper. А fastcgi_cache_use_stale и fastcgi_cache_lock не дают сотням посетителей одновременно запускать PHP, когда запись в кеше устарела. На виртуальном хостинге доступа к nginx обычно нет, поэтому ту же роль выполняет плагин: WP Super Cache, W3 Total Cache или LiteSpeed Cache, если сервер работает на LiteSpeed. Какие еще бывают уровни кеширования, описано в материале про кеш на хостинге.

Шаг 2. OPcache

OPcache держит скомпилированный PHP-код в памяти, чтобы не разбирать тысячи файлов WordPress на каждый запрос. С выключенным OPcache стенд дал TTFB 190-195 мс и 9,7 запроса в секунду, с включенным 41-45 мс и 42-44 запроса, то есть примерно в 4,5 раза быстрее. Именно эту скорость получают все, кого обходит кеш страниц: администраторы, редакторы, покупатели.

Проверяйте OPcache для сайта, а не в терминале: консольный PHP и PHP-FPM могут отличаться. На стенде php -v показывает PHP 8.4, а сайт работает на PHP 8.3-FPM, и для консоли OPcache там выключен. Надежнее создать в корне сайта временный файл со строкой <?php var_dump(opcache_get_status(false)['opcache_enabled'] ?? false);, открыть его в браузере (на стенде он показал bool(true)) и сразу удалить. Стандартных настроек пакета Ubuntu на стенде хватило.

Шаг 3. Найдите плагин, который тормозит

Имитация тяжелого плагина подняла TTFB с 41-45 до 309-311 мс. Найти виновника можно тремя способами.

Query Monitor. Плагин для администратора, который на верхней панели показывает количество и время SQL-запросов с разбивкой по плагинам, а также внешние HTTP-запросы.

wp profile. Команда из пакета wp-cli/profile-command (устанавливается через wp package install wp-cli/profile-command) показывает, на каком этапе загрузки тратится время. Реальный вывод со стенда с включенной имитацией:

$ wp profile stage --url=http://127.0.0.1:8080/post-293/ --fields=stage,time,query_time,query_count
stage        time      query_time  query_count
bootstrap    0.2059s   0.0017s     4
main_query   0.2701s   0.0107s     155
template     0.0751s   0.0062s     20
total (3)    0.5512s   0.0186s     179

$ wp profile stage main_query --spotlight --url=http://127.0.0.1:8080/post-293/ --fields=hook,time,query_time,query_count
hook                   time      query_time  query_count
pre_get_posts:before   0.2779s   0.0151s     150
wp                     0.2765s   0.0151s     150

Без имитации этап main_query занимал 0,005 с и 5 запросов, с ней 0,27 с и 155, а --spotlight сузил поиск до хука wp. Абсолютные времена здесь выше, чем через браузер, потому что WP-CLI работает без OPcache, но сравнивать этапы это не мешает. Подкоманда wp profile hook, которая называет конкретную функцию, на WP-CLI 2.12 со стенда не запустилась: ей нужна более новая версия WP-CLI.

Медленный лог PHP-FPM. Если есть доступ к настройкам пула, две строки заставят FPM записывать стек вызовов каждого запроса дольше секунды:

; /etc/php/8.3/fpm/pool.d/www.conf
request_slowlog_timeout = 1s
slowlog = /var/log/php8.3-fpm-slow.log

Для проверки мы добавили тестовую функцию, которая 1,5 с «ждет API». Лог сразу показал и функцию, и файл:

[24-Oct-2026 23:45:18]  [pool www] pid 17625
script_filename = /var/www/bench/index.php
[0x00007f56fc215510] usleep() /var/www/bench/wp-content/mu-plugins/r1-slowapi.php:3
[0x00007f56fc2154c0] r1_bench_fetch_remote_rates() /var/www/bench/wp-content/mu-plugins/r1-slowapi.php:4
[0x00007f56fc215440] {closure}() /var/www/bench/wp-includes/class-wp-hook.php:324
...
[0x00007f56fc215100] wp() /var/www/bench/wp-blog-header.php:16

Что делать с виновником: обновить, заменить более легким аналогом или попросить разработчика кешировать ответ внешнего API (например, в transient), чтобы сайт не ждал его при каждом открытии страницы.

Шаг 4. Воркеры PHP-FPM

Воркер PHP-FPM обрабатывает один запрос за раз, остальные ждут в очереди. Мы подали 20 одновременных медленных запросов (тяжелый плагин, без кеша) при pm.max_children = 5 и 20.

Время ответа при 20 одновременных запросах: медиана 1272 мс с 5 воркерами PHP-FPM и 846 мс с 20, p95 1693 и 1642 мс
Больше воркеров уменьшило медиану, но не хвост: два ядра процессора остались теми же

С 20 воркерами медиана упала с 1272 до 846 мс, а пропускная способность выросла с 14,0 до 18,8 запроса в секунду. Однако p95 почти не изменился (1693 и 1642 мс): ядер процессора осталось два, и воркеры начали за них конкурировать. К тому же каждый воркер на стенде занимал 40-42 МБ памяти, так что 20 воркеров это около 0,8 ГБ только на PHP. Ориентировочное правило: pm.max_children равен памяти, которую можно отдать PHP, деленной на размер одного воркера:

$ ps --no-headers -o rss,cmd -C php-fpm8.3
10644 php-fpm: master process (/etc/php/8.3/fpm/php-fpm.conf)
42888 php-fpm: pool www
41148 php-fpm: pool www

Больше воркеров только сокращают очередь, а не ускоряют код. Другие параметры стека описаны в материале про настройку хостинг-серверов.

Шаг 5. Сжатие gzip

HTML главной страницы стенда весил 56,8 КБ без сжатия и 12,3 КБ с gzip, в 4,6 раза меньше. Подвох в том, что стандартный nginx.conf в Ubuntu включает gzip только для HTML: строка gzip_types там закомментирована. Из-за этого файл стилей блоков ядра WordPress (style.min.css) отдавался несжатым, 114 706 байт. После добавления gzip_types тот же файл весил 15 608 байт:

gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_vary on;
gzip_proxied any;
gzip_types text/css application/javascript application/json image/svg+xml text/xml application/xml application/rss+xml;

Проверить свой сайт можно, сравнив размер ответа с запросом сжатия и без него:

$ curl -s -o /dev/null -w "%{size_download}\n" http://127.0.0.1:8080/
56776
$ curl -s -o /dev/null -H "Accept-Encoding: gzip" -w "%{size_download}\n" http://127.0.0.1:8080/
12319

Шаг 6. Изображения и CDN

Изображения не влияют на TTFB, но чаще всего именно они составляют основной вес страницы. Мы пропустили два реальных фото в формате PNG через редактор изображений WordPress (GD) с качеством по умолчанию, без изменения размера:

Фото PNG JPEG (качество 82) WebP (86) AVIF (82)
741×500 пикселей 630 КБ 84,4 КБ 76,3 КБ 86,3 КБ
600×400 пикселей 456 КБ 50,1 КБ 49,0 КБ 52,5 КБ

Главный выигрыш дает отказ от PNG для фотографий: в 7-9 раз. А вот переход с JPEG на WebP при стандартных настройках WordPress сэкономил лишь 2-10%, AVIF через GD с качеством 82 получился даже больше JPEG. Так что WebP стоит включать, но без ожидания чуда. Больше дают правильный размер картинок (WordPress сам уменьшает оригиналы шире 2560 пикселей и создает промежуточные размеры) и встроенная ленивая загрузка. Большие фото с телефона и CDN мы не измеряли: у локального стенда нет сетевой задержки, которую сокращает CDN.

Шаг 7. Object cache (Redis)

Redis object cache хранит результаты запросов к базе между открытиями страниц. На стенде (Redis 7.0, php-redis и минимальный drop-in) количество SQL-запросов упало с 22-29 до нуля, TTFB с 43,7-46,8 до 39,6-39,7 мс, пропускная способность выросла на 10-20%. Тяжелый плагин Redis не спас: его 150 прямых запросов и ожидание API никуда не делись, TTFB 306 мс против 311-313 мс без Redis. База на стенде маленькая и локальная, поэтому на большом магазине или с удаленной БД выигрыш может быть больше. Полезнее всего object cache там, где не работает кеш страниц: личные кабинеты, корзина, админка.

Шаг 8. Autoload: проверьте, но не начинайте с него

Опции с пометкой autoload WordPress загружает на каждом запросе. Мы добавили 60 опций по 50 КБ (всего около 3 МБ), и медианный TTFB вырос лишь на 0,4-4,4 мс, p90 на 8-14 мс. Значит, autoload стоит чистить, когда он достигает десятков мегабайт или когда раздел «Здоровье сайта» предупреждает о его размере, но не вместо кеша и OPcache. Проверить размер и самые крупные опции:

$ wp option list --autoload=on --format=total_bytes
44236
$ wp db query "SELECT option_name, LENGTH(option_value) bytes FROM wp_options WHERE autoload IN ('yes','on','auto','auto-on') ORDER BY bytes DESC LIMIT 5"
option_name                         bytes
_transient_wp_core_block_css_files  20490
_transient_wp_styles_for_blocks     10690
rewrite_rules                       8495
wp_user_roles                       3133
cron                                1027

44 КБ: норма для чистого сайта. Если же вверху списка оказались сотни килобайт от давно удаленного плагина, такую опцию можно убрать из автозагрузки командой wp option set-autoload имя_опции off, заранее сделав резервную копию базы.

Виртуальный хостинг или VPS: что вы можете сделать

Шаг Виртуальный хостинг VPS
Кеш страниц Плагин кеша (WP Super Cache, W3 Total Cache, LiteSpeed Cache на LiteSpeed) nginx fastcgi_cache с конфигом выше
OPcache Проверить тестовым файлом; если выключен, включить в настройках PHP в панели или через поддержку opcache.enable=1 в php.ini именно для FPM
Медленные плагины Query Monitor Query Monitor, wp profile, медленный лог PHP-FPM
Воркеры PHP Лимиты задает хостер; если сайт в них упирается, нужен другой тариф pm.max_children по памяти, как в шаге 4
Сжатие Обычно уже включено, проверьте через curl gzip_types в nginx
Object cache Только если хостинг предоставляет Redis или Memcached redis-server, php-redis и плагин object cache

Если после кеша, OPcache и разбора плагинов страницы без кеша все равно отвечают медленно, а воркеров не хватает в часы пик, это повод посмотреть на более мощный тариф или VPS; как понять, какой тип хостинга выбрать, мы объясняем отдельно. Требования WordPress к серверу собраны в обзоре хостинг для WordPress, а тарифы RichHost представляют собой виртуальный хостинг на NVMe-дисках с собственной панелью управления и ИИ-помощником и бесплатным SSL Let’s Encrypt.

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

Нужен ли плагин кеша, если на сервере уже есть кеш nginx?

Нет. Два кеша страниц одновременно только усложняют очистку. Оставьте один: серверный на VPS или плагин на виртуальном хостинге.

Почему PageSpeed Insights почти не изменился после кеша?

PageSpeed оценивает всю страницу (изображения, скрипты, шрифты) и измеряет с серверов Google, то есть с сетевой задержкой. Кеш сокращает только серверную часть, остальное дают шаги 5 и 6.

Сколько плагинов: это слишком много?

Количество плагинов мы не измеряли, но один плагин со 150 запросами и обращением к API стоил около 265 мс на каждый запрос. Важно не количество, а то, что каждый плагин делает при каждом открытии страницы; это показывают Query Monitor и wp profile.

Еще по теме

Все статьи
Защита WordPress: проверили 15 советов по безопасности на стенде, обязательных 8
WordPress-хостинг10.11.2026

Защита WordPress: проверили 15 советов по безопасности на стенде, обязательных 8

Проверили 15 популярных советов по защите WordPress на тестовом стенде: 8 обязательных, 4 желательных, остальные лишние. Реальные ответы сервера до и после…

«На сайте произошла критическая ошибка» в WordPress: как исправить
WordPress-хостинг21.10.2026

«На сайте произошла критическая ошибка» в WordPress: как исправить

Пошагово: как найти причину сообщения «На сайте произошла критическая ошибка» и белого экрана WordPress через письмо администратору, режим восстановления, WP_DEBUG_LOG и отключение…

Как перенести WordPress на другой хостинг: плагином и вручную
WordPress-хостинг07.10.2026

Как перенести WordPress на другой хостинг: плагином и вручную

Три способа перенести WordPress на другой хостинг: Duplicator, All-in-One WP Migration и вручную через SSH. Команды для файлов и базы, безопасная замена…