Диагностика проблемы: зачем нужна отложенная загрузка товаров по атрибутам в WooCommerce
В интернет-магазинах на WooCommerce с большим количеством товаров и вариаций возникает проблема снижения скорости загрузки страниц каталога. Особенно если на странице одновременно выводятся все вариации и фильтры по атрибутам. Это приводит к долгой загрузке, ухудшению пользовательского опыта и негативному влиянию на SEO. Отложенная загрузка (lazy load) товаров по атрибутам позволяет загружать сначала базовый набор товаров, а последующие — динамически при выборе атрибутов или прокрутке страницы.
Как работает отложенная загрузка товаров по атрибутам
Основная идея — изначально подгружать только часть товаров, например, без применения фильтров или с минимальным набором. При выборе пользователем атрибутов (цвет, размер, бренд) динамически отправлять AJAX-запрос и подгружать соответствующие товары без перезагрузки страницы.
Это снижает нагрузку на сервер и ускоряет рендеринг страницы. В WooCommerce для этого используют AJAX-хуки, WP_Query с параметрами атрибутов и JavaScript для обработки событий.
Пошаговое решение: реализация отложенной загрузки товаров по атрибутам в WooCommerce
1. Подключаем AJAX обработчик в functions.php
add_action('wp_enqueue_scripts', function() {
wp_enqueue_script('wc-attr-filter', get_stylesheet_directory_uri() . '/js/wc-attr-filter.js', ['jquery'], null, true);
wp_localize_script('wc-attr-filter', 'wcAttrFilter', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wc_attr_filter_nonce'),
]);
});
add_action('wp_ajax_filter_products_by_attr', 'filter_products_by_attr_callback');
add_action('wp_ajax_nopriv_filter_products_by_attr', 'filter_products_by_attr_callback');
function filter_products_by_attr_callback() {
check_ajax_referer('wc_attr_filter_nonce', 'nonce');
$attribute = sanitize_text_field($_POST['attribute']);
$value = sanitize_text_field($_POST['value']);
$tax_query = [
[
'taxonomy' => 'pa_' . $attribute,
'field' => 'slug',
'terms' => $value,
],
];
$args = [
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => $tax_query,
];
$query = new WP_Query($args);
if ($query->have_posts()) {
ob_start();
woocommerce_product_loop_start();
while ($query->have_posts()) {
$query->the_post();
wc_get_template_part('content', 'product');
}
woocommerce_product_loop_end();
wp_reset_postdata();
$products_html = ob_get_clean();
wp_send_json_success($products_html);
} else {
wp_send_json_error('Товары не найдены.');
}
wp_die();
}
2. Создаем JavaScript для отправки AJAX-запроса при выборе атрибута
jQuery(document).ready(function($) {
$('.attribute-filter').on('change', function() {
var attribute = $(this).data('attribute');
var value = $(this).val();
$.ajax({
url: wcAttrFilter.ajax_url,
method: 'POST',
data: {
action: 'filter_products_by_attr',
nonce: wcAttrFilter.nonce,
attribute: attribute,
value: value
},
beforeSend: function() {
$('#products-container').html('<p>Загрузка товаров...</p>');
},
success: function(response) {
if (response.success) {
$('#products-container').html(response.data);
} else {
$('#products-container').html('<p>' + response.data + '</p>');
}
},
error: function() {
$('#products-container').html('<p>Ошибка при загрузке товаров.</p>');
}
});
});
});
Как проверить, что отложенная загрузка товаров работает корректно
- Откройте страницу каталога с фильтрами по атрибутам.
- Выберите фильтр (например, цвет или размер). Вместо полной перезагрузки страницы должен появиться индикатор загрузки.
- После загрузки отображается список товаров, соответствующих выбранному атрибуту.
- Проверьте консоль браузера на отсутствие ошибок JavaScript и успешные AJAX-запросы в сети (Network).
- Если в базе нет товаров под выбранный атрибут — выводится корректное сообщение.
Частые ошибки и как их исправить
- Неверный слаг атрибута в tax_query: убедитесь, что атрибуты называются с префиксом
pa_. Например, для атрибута color —pa_color. - Отсутствие nonce или его неверная проверка: обязательно используйте
wp_create_nonceиcheck_ajax_refererдля защиты AJAX-запросов. - JavaScript не подключен или ошибки в скрипте: проверьте подключение скрипта и убедитесь, что jQuery загружен.
- WooCommerce шаблоны не подгружаются: используйте стандартные функции WooCommerce для вывода товаров —
woocommerce_product_loop_start,wc_get_template_part,woocommerce_product_loop_end.
Практические советы по оптимизации и безопасности
- Кэшируйте результаты запросов по атрибутам, если данные редко меняются, чтобы снизить нагрузку на сервер.
- Ограничивайте количество товаров на страницу, чтобы не перегружать пользователя и сервер — оптимально 12-20.
- Используйте
wp_localize_scriptдля передачи данных из PHP в JS — это безопаснее, чем хардкодить URL или nonce. - Регулярно обновляйте WooCommerce и темы, чтобы избежать уязвимостей.
- Тестируйте работу фильтров на разных устройствах и браузерах для стабильности.
Сравнение вариантов реализации отложенной загрузки товаров по атрибутам
| Вариант | Описание | Плюсы | Минусы |
|---|---|---|---|
| Чистый код (как в статье) | Реализация через AJAX и WP_Query в functions.php и JS | Гибкость, полный контроль, отсутствие лишних плагинов | Требует знаний PHP/JS, больше времени на поддержку |
| Плагины для фильтрации | Использование WooCommerce фильтров и lazy load плагинов | Быстрая настройка, поддержка, готовые UI | Может замедлить сайт, ограниченная кастомизация |
| Серверные решения (ElasticSearch) | Интеграция с ElasticSearch для быстрого поиска и фильтрации | Очень быстрая фильтрация, масштабируемость | Сложная настройка, дополнительные расходы |