Оптимизация запросов WordPress с помощью фильтра pre_get_posts

Что такое фильтр pre_get_posts и зачем он нужен

Фильтр pre_get_posts позволяет изменять параметры основного и дополнительных запросов WordPress до их выполнения. С его помощью можно оптимизировать выборку записей, исключить ненужные данные или добавить условия, что важно для производительности и корректности вывода контента.

Диагностика проблемы: медленные или избыточные запросы

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

Для диагностики используйте плагин Query Monitor. Он покажет список запросов к базе, время их выполнения и параметры. Анализируйте медленные запросы и ищите возможности их оптимизировать.

Пошаговое решение: добавляем фильтр pre_get_posts

Рассмотрим пример оптимизации главного запроса на странице категории. Задача — исключить из вывода записи с определённым мета-ключом или статусом, а также ограничить количество выводимых записей для ускорения загрузки.

function optimize_category_query(\WP_Query $query) {
    if (is_admin() || !$query->is_main_query()) {
        return; // Не изменяем запрос в админке и неосновные запросы
    }

    if ($query->is_category()) {
        // Исключаем записи с мета-ключом 'exclude_from_cat' = '1'
        $meta_query = [
            [
                'key' => 'exclude_from_cat',
                'compare' => '!=',
                'value' => '1'
            ]
        ];
        $query->set('meta_query', $meta_query);

        // Ограничиваем количество записей на странице
        $query->set('posts_per_page', 10);

        // Явно указываем статус публикации
        $query->set('post_status', 'publish');
    }
}
add_action('pre_get_posts', 'optimize_category_query');

Этот код добавляем в файл functions.php вашей темы или в кастомный плагин. Он проверяет, что запрос основной и не в админке, затем для категории добавляет условие исключения по мета-ключу, ограничивает количество записей и устанавливает статус.

Пример более сложного условия с несколькими параметрами

function optimize_search_query(\WP_Query $query) {
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    if ($query->is_search()) {
        // Исключаем страницы из результатов поиска
        $query->set('post_type', 'post');

        // Добавляем мета-запрос для фильтрации по кастомному полю
        $query->set('meta_query', [
            [
                'key' => 'custom_field',
                'value' => 'allowed',
                'compare' => '='
            ]
        ]);

        // Уменьшаем количество результатов
        $query->set('posts_per_page', 5);
    }
}
add_action('pre_get_posts', 'optimize_search_query');

Как проверить, что фильтр сработал

  • Откройте нужную страницу (например, категорию или поиск) и убедитесь, что количество записей соответствует заданному лимиту.
  • Используйте Query Monitor для проверки параметров запроса — там должны отображаться изменённые настройки (meta_query, posts_per_page, post_status).
  • Проверьте, что записи с заданным мета-ключом исключены из вывода.

Частые ошибки при работе с pre_get_posts

  • Изменение запросов в админке. Это может привести к сбоям, поэтому всегда проверяйте is_admin().
  • Отсутствие проверки основного запроса. Фильтр срабатывает на все запросы, поэтому используйте $query->is_main_query() для ограничения.
  • Перезапись уже заданных параметров. Например, если тема или плагины уже модифицируют запрос, ваши изменения могут конфликтовать. В этом случае стоит использовать приоритет хука выше (например, 20).
  • Неправильный синтаксис мета-запросов. Для нескольких условий используйте массивы с правильной структурой.

Практические советы по производительности и безопасности

  • Добавляйте только необходимые условия, чтобы не создавать избыточных сложных запросов.
  • Используйте posts_per_page для ограничения выборки и избегайте вывода слишком большого количества записей.
  • Кэшируйте результаты запросов с помощью Transients API или внешних кешей, если данные не меняются часто.
  • Проверяйте вводимые параметры, если они зависят от GET-запросов, чтобы избежать SQL-инъекций.

Сравнение вариантов изменения запросов

ВариантПримерПлюсыМинусы
Использовать pre_get_postsИзменение параметров основного запросаГибко, работает для основного и дополнительных запросовНужно аккуратно фильтровать, чтобы не сломать админку
Делать отдельный WP_QueryНовый запрос с нужными параметрамиКонтролируемый, не влияет на основной запросМожет быть дублирование запросов, нагрузка на базу
Использовать плагины оптимизации запросовClearfy Pro, WP RocketПростота, дополнительные функции кэшированияМеньше контроля, возможны конфликты
Как удалить ненужные shortcode из контента WordPress
05.01.2026
Как удалить Embed код из WordPress без плагинов
01.01.2026
Добавление авторизации через телефон в WordPress
04.04.2026
Как удалить избитые шорткоды в WordPress: практические методы и примеры кода
11.03.2026
Как полностью отключить Gutenberg в WordPress
21.12.2025