WooCommerce: использование иерархии категорий для фильтрации товаров без задержек

|

Диагностика проблемы с медленной фильтрацией по иерархии категорий

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

Для диагностики проблем используйте инструменты разработчика браузера (Network, Console) и проверьте SQL-запросы к базе через плагин Query Monitor. Часто причиной становится неэффективный запрос к базе из-за избыточных JOIN или отсутствия кеширования.

Пошаговое решение: оптимизация фильтрации по иерархии категорий

1. Использование правильных хуков для фильтрации товаров

Для кастомной фильтрации товаров по категориям с учетом иерархии используйте хук pre_get_posts. Пример кода для фильтрации по выбранной категории и ее дочерним категориям:

add_action('pre_get_posts', function($query) {
    if (is_admin() || !$query->is_main_query()) {
        return;
    }
    if (is_shop() || is_product_category()) {
        $cat = get_queried_object();
        if ($cat && isset($cat->term_id)) {
            $child_cats = get_terms(array(
                'taxonomy' => 'product_cat',
                'child_of' => $cat->term_id,
                'fields' => 'ids',
                'hide_empty' => false
            ));
            $cat_ids = array_merge(array($cat->term_id), $child_cats);
            $tax_query = array(
                array(
                    'taxonomy' => 'product_cat',
                    'field' => 'term_id',
                    'terms' => $cat_ids,
                    'include_children' => false,
                    'operator' => 'IN'
                )
            );
            $query->set('tax_query', $tax_query);
        }
    }
});

2. Кеширование результатов запросов и данных категорий

Чтобы уменьшить нагрузку, кешируйте результат вызова get_terms() и сложных запросов. Используйте Transients API:

function get_cached_child_categories($parent_id) {
    $cache_key = 'child_cats_' . $parent_id;
    $cached = get_transient($cache_key);
    if ($cached !== false) {
        return $cached;
    }
    $terms = get_terms(array(
        'taxonomy' => 'product_cat',
        'child_of' => $parent_id,
        'fields' => 'ids',
        'hide_empty' => false
    ));
    set_transient($cache_key, $terms, 12 * HOUR_IN_SECONDS);
    return $terms;
}

Вызовите эту функцию вместо get_terms() в фильтре выше.

3. Использование AJAX с правильными параметрами

Убедитесь, что AJAX-запросы фильтра посылаются с верными параметрами категорий и корректно обрабатываются на бэкенде. Для кастомного AJAX обработчика добавьте в functions.php:

add_action('wp_ajax_filter_products', 'filter_products_callback');
add_action('wp_ajax_nopriv_filter_products', 'filter_products_callback');

function filter_products_callback() {
    $cat_id = intval($_POST['cat_id']);
    if (!$cat_id) {
        wp_send_json_error('Invalid category ID');
    }
    $child_cats = get_cached_child_categories($cat_id);
    $cat_ids = array_merge(array($cat_id), $child_cats);
    $args = array(
        'post_type' => 'product',
        'tax_query' => array(
            array(
                'taxonomy' => 'product_cat',
                'field' => 'term_id',
                'terms' => $cat_ids,
                'include_children' => false
            )
        ),
        'posts_per_page' => 20
    );
    $query = new WP_Query($args);
    ob_start();
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            wc_get_template_part('content', 'product');
        }
    } else {
        echo '<p>Товары не найдены</p>';
    }
    wp_reset_postdata();
    $content = ob_get_clean();
    wp_send_json_success(array('html' => $content));
}

Проверка результата после внедрения

Частые ошибки и способы их исправления

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

add_action('edited_product_cat', 'clear_category_cache');
add_action('created_product_cat', 'clear_category_cache');

function clear_category_cache($term_id) {
    delete_transient('child_cats_' . $term_id);
}

Сравнение вариантов решения фильтрации по иерархии категорий

ВариантОписаниеПлюсыМинусы
Стандартный WooCommerce фильтрИспользование встроенных виджетов и фильтровПростота, интеграция с темойМедленная работа на больших каталогах, проблемы с AJAX
Кастомный pre_get_posts с кешированиемНастройка фильтра через хук с кешем категорийУскоряет запросы, учитывает иерархиюТребует разработки и поддержки
Кастомный AJAX-обработчикФильтрация через AJAX запросы с кешем и WP_QueryБыстрая динамическая фильтрация без перезагрузкиНужна доработка фронтенда и безопасности
Как создать иерархию кастомных типов постов с поддержкой REST API в WordPress
11.03.2026
Как удалить пустое разделение в иерархии WordPress: практическое руководство
11.04.2026
Как создать иерархию пользователей с поддержкой REST API в WordPress
05.04.2026
WooCommerce: как правильно настроить иерархию категорий и проблемы с производительностью
17.04.2026
WooCommerce: устранение проблем с автоматическим установлением родительских категорий при импорте товаров
29.05.2026
×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее