Рефакторинг темы WordPress под нагрузкой: что ломается первым
Старая тема WordPress обычно замедляет сайт не одним большим дефектом, а цепочкой мелких решений: тяжёлые WP_Query, запросы в цикле, автозагрузка настроек и динамический HTML без кеша. Разбираем, что проверять первым и как менять без простоя.

На загруженном сайте WordPress тема чаще всего ломается не визуально, а по времени ответа: каталог начинает отдавать страницы дольше, PHP-процессы занимают весь пул, а база данных получает десятки повторяющихся запросов на один экран. Для темы, которую пять лет дописывали поверх старого кода, опаснее всего не полный переписанный шаблон, а постепенный рефакторинг без замеров. Ниже — разбор для WordPress 6.x и PHP 8.2+; перед изменениями проверьте фактические версии на продакшене.
Что обычно ломается первым
При нагрузке тема становится частью цепочки: веб-сервер передаёт запрос PHP, WordPress собирает окружение, тема вызывает запросы к базе и формирует HTML, затем кеши либо отдают результат, либо пропускают весь путь заново. Если узкое место находится в шаблоне, увеличение числа воркеров не лечит причину. Оно лишь позволяет одновременно запустить больше дорогих операций.
Рефакторинг темы под нагрузкой начинается не с переименования функций, а с ответа на вопрос: какой запрос повторяется сотни раз и почему его вообще выполняет шаблон.
1. Дополнительные запросы внутри циклов
Старый шаблон часто получает список записей одним WP_Query, а затем внутри цикла отдельно ищет автора, связанные записи, термины или изображения. Один материал превращается в десятки обращений к базе. На тестовой странице это может быть незаметно, но при параллельных запросах растёт время работы PHP и число занятых соединений с базой.
Проверять нужно не только основной запрос, но и вызовы в partial-шаблонах: карточка товара может запускать собственный поиск, а вложенный блок — ещё один. Query Monitor или профилировщик PHP помогут увидеть количество запросов и их стек вызовов. Само наличие большого числа запросов не доказывает проблему: важны повторяемость, время выполнения и рост показателей вместе с количеством карточек.
2. Тяжёлый WP_Query без ограничения результата
Проблема возникает, когда тема запрашивает больше записей, полей или сортировок, чем реально выводит. Особенно дорогими бывают сложные сочетания meta_query, сортировка по метаполю и поиск по большому объёму пользовательских метаданных. Если шаблон показывает шесть карточек, запрос не должен молча собирать сотни объектов только потому, что старый код рассчитывал на другой экран.
Отдельный риск — повторный запрос той же подборки в шапке, основном контенте и подвале. Внешне блоки могут выглядеть разными, но фильтровать одну и ту же таксономию или тип записи. Сначала зафиксируйте список данных, который действительно нужен странице, затем убирайте лишние запросы. Оптимизацию SQL без понимания бизнес-логики лучше не начинать.
3. Запросы к базе в каждом рендере
Настройки темы, счётчики, ссылки на блоки и флаги могут читаться напрямую из базы при каждом открытии страницы. Если эти данные редко меняются, их постоянное получение не даёт пользователю пользы, но увеличивает работу PHP и базы.
Проверьте вызовы get_option(), получение термов, метаполей и пользовательских данных. Некоторые значения WordPress кеширует в рамках запроса, но это не означает, что любой сложный сбор данных становится бесплатным. Повторное обращение к уже полученному объекту и повторная сборка той же структуры — разные операции; измеряйте обе.
Термин: автозагрузка опций — механизм, при котором значения опций с соответствующим признаком загружаются при запуске WordPress. Большой объём таких данных увеличивает память и время подготовки каждого запроса, даже если конкретная страница их не использует.
Где искать узкое место до рефакторинга
Сначала снимите базовую линию. Иначе после изменений вы не поймёте, ускорили ли страницу или просто получили другой набор случайных условий.
- Разделите страницы по сценариям. Возьмите главную, архив, страницу записи, поиск и самый тяжёлый экран каталога. Для каждой запишите время ответа, размер HTML, число запросов к базе, пиковое потребление памяти и количество выполненных HTTP-запросов. Проверка: у вас есть таблица с одинаковым набором показателей для каждой страницы.
- Снимите профиль без кеша и с кешем. Кеш страницы может скрыть дорогой PHP-код, а его отсутствие создаёт нагрузку, которой не увидит обычный посетитель. Проверка: вы понимаете, какие операции выполняются при cache hit и какие остаются на origin.
- Найдите самые дорогие вызовы. Смотрите не только на SQL, но и на внешние HTTP-запросы, обработчики фильтров и генерацию изображений. Проверка: у каждого кандидата есть измерение и файл, который его запускает.
- Зафиксируйте условия теста. Укажите версию WordPress, PHP, размер базы, включённые плагины, тип кеша и число параллельных запросов. Проверка: другой инженер может повторить тест и получить сопоставимый результат.
Тестировать только на локальной копии опасно: объём данных, индексы, кеши и конфигурация PHP-FPM там обычно отличаются. При отсутствии стенда используйте обезличенную копию и ограниченное окно нагрузки, не направляя генератор запросов на продакшен без согласования.
Четыре стратегии рефакторинга
| Подход | Что меняется | Плюс | Цена и риск |
|---|---|---|---|
| Точечная оптимизация | Убираются повторные запросы, сокращается объём данных, исправляются самые дорогие шаблоны | Небольшой радиус изменений, проще откатить | Старые архитектурные ограничения остаются |
| Выделение слоя данных | Запросы и подготовка данных уходят из шаблонов в отдельные функции или классы | Легче тестировать и повторно использовать результат | Нужно аккуратно сохранить хуки и контракты темы |
| Постепенный переход на блоки | Часть шаблонов заменяется block-шаблонами и паттернами WordPress | Меньше жёстко зашитой разметки, удобнее управлять контентом | Потребуется проверить совместимость плагинов и редактора |
| Полная смена темы | Старый слой заменяется новой темой целиком | Можно пересобрать архитектуру без наследования старых решений | Высокий риск визуальных регрессий, потери хуков и SEO-логики |
Почему шаблон не должен быть центром всей логики
Шаблон отвечает за вывод, а не за поиск всех данных, расчёт бизнес-правил и обращения к внешним сервисам. Когда эти обязанности смешаны, любое изменение разметки меняет нагрузку на базу. Выделение подготовки данных уменьшает такой риск: запрос выполняется в одном месте, результат можно проверить отдельно, а карточка получает уже готовую структуру.
Это не повод механически переносить весь код в один «сервис темы». Если слой данных просто скрывает прежние вызовы, система не ускорится. Сначала сократите число операций, затем отделите их от HTML.
Что проверять в пяти старых местах
Главная страница
На главной часто одновременно живут последние записи, подборки по рубрикам, промоблоки, популярные материалы и виджеты. Проверьте, не выбирается ли одна запись несколько раз разными блоками. Если секции требуют разные сортировки, заранее определите, какие из них должны быть динамическими, а какие можно отдавать из кеша.
Архивы и поиск
Архивы создают нагрузку количеством результатов, а поиск — дорогими условиями и неожиданными запросами к метаданным. Ограничение числа карточек в шаблоне не всегда ограничивает основной запрос: проверьте параметры самого WP_Query и пагинацию. Для поиска отдельно измерьте пустой результат, одну найденную запись и длинный список совпадений.
Карточка записи
Внутри карточки ищите повторное получение автора, терминов, миниатюры и связанных записей. Сложность особенно быстро растёт в сетках: операция, дешёвая для одной записи, становится дорогой для двадцати. Не заменяйте все вызовы глобальным кешем без проверки актуальности данных: устаревшая карточка может быть хуже медленной.
Хуки и фильтры
За пять лет плагины могли добавить обработчики в те же хуки, на которых держится тема. Один фильтр способен несколько раз менять контент или запускать тяжёлую обработку. Перед удалением хука найдите его потребителей: отключение старой функции может сломать микроразметку, формы, рекламу или интеграцию с магазином.
Внешние запросы
Погода, курсы валют, рекомендации и виджеты соцсетей не должны блокировать формирование страницы без тайм-аута и кеша. Внешний сервис может отвечать медленно или быть недоступным. Для каждого вызова зафиксируйте тайм-аут, поведение при ошибке и срок хранения ответа. Секреты интеграций не храните в файлах темы и не добавляйте в репозиторий.
Граничные случаи: где оптимизация ломается
Главная ошибка — считать ускорение локальным свойством одного шаблона. Поведение меняется на границах системы.
- Поломка кеша. Если HTML зависит от пользователя, корзины, региона или роли, общий кеш может показать одному посетителю данные другого. Для персонализированных фрагментов нужна отдельная стратегия, а не простое увеличение времени жизни страницы.
- Неверная инвалидация. Кеш списка может пережить публикацию, удаление или смену рубрики. После оптимизации проверьте не только скорость, но и момент, когда пользователь увидит новое содержимое.
- Редкие страницы. Главная может работать быстро, а поиск по редкому термину или архив с большой пагинацией — медленно. Профилируйте худший сценарий, а не только популярный URL.
- Плагины. Тема может быть быстрой в изоляции, но медленной вместе с SEO, аналитикой, магазином и конструктором форм. Меняйте по одному слою и сохраняйте список включённых расширений.
- Память PHP. Уменьшение SQL-запросов не помогает, если код загружает огромные массивы постов и метаданных. Смотрите пик памяти и ошибки исчерпания лимита отдельно от времени ответа.
Как выкатывать изменения без простоя
Сначала вынесите один повторяющийся запрос или один тяжёлый блок. Сохраните старый путь за переключателем конфигурации, если архитектура проекта это позволяет, и сравните одинаковые сценарии. После этого проверьте HTML, статусы ответов, пагинацию, канонические ссылки, микроразметку и работу форм.
Критерий готовности должен включать не только среднее время ответа. Зафиксируйте процентиль задержки, ошибки PHP, число запросов к базе, использование памяти и долю попаданий в кеш. Среднее значение легко скрывает редкие, но болезненные зависания.
Если показатель ухудшился, откатывайте последний небольшой шаг, а не весь годовой рефакторинг. Малые изменения дороже по количеству релизов, зато позволяют связать регрессию с конкретным решением.
Что делать дальше
Начните с одной страницы, которая приносит больше всего трафика или чаще всего упирается в лимиты PHP. Снимите профиль WordPress 6.x на текущей теме, составьте список пяти самых дорогих операций и выберите одну, которую можно изменить без перестройки всей разметки. После релиза наблюдайте за p95 времени ответа, ошибками PHP-FPM, количеством SQL-запросов и попаданиями в кеш. Инвалидацию кеша, миграцию на block theme и оптимизацию индексов базы лучше вынести в отдельные задачи, а не смешивать с первым проходом по шаблонам.
Дефектный акт по фото: Осмотр по фотографиям: классификация дефектов, ссылки на нормы, требования к устранению. Готовый акт в Word.
Спросить за 80 ₽Источники: WordPress Developer Resources: Performance, WordPress Developer Resources: WP_Query
Частые вопросы
Нужно ли переписывать тему целиком, если ей пять лет?
Как понять, что тормозит именно тема, а не плагин?
Стоит ли сначала включить кеш страниц?
Что будет, если удалить старый хук из темы?
Можно ли ускорить тему без изменения базы данных?
Какие версии нужно указать перед рефакторингом?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.