Ускорение больших фильтров категорий WooCommerce: Slideout с ленивой загрузкой
Когда у вас есть родительская категория с:
- Большим количеством товаров (500–1000+)
- Глубокой иерархией категорий (несколько уровней подкатегорий)
- Включенным динамическим пересчетом
Фильтр товаров может генерировать сотни SQL-запросов при каждой загрузке страницы, даже если пользователь никогда не использует фильтр. Это приводит к:
- Медленной загрузке страницы (10+ секунд)
- Ошибкам 504 Gateway Timeout
- Высокой нагрузке на сервер
- Плохому пользовательскому опыту
Почему это происходит
При включенном динамическом пересчете, WOOF должен:
- Рекурсивно обрабатывать все дочерние категории
- Выполнять SQL-запросы для каждого термина, чтобы посчитать товары
- Рассчитывать количества с учетом контекста текущей категории
Пример: Категория «Солнцезащитные очки» с подкатегориями (Мужские → Женские → Формы → Бренды) генерирует огромную нагрузку на запросы.
Традиционные решения (Недостаточно)
❌ Скрытие слайдаута с помощью CSS/правил отображения – Фильтр все равно обрабатывается на сервере
❌ Отключение динамического пересчета – Теряется важный функционал
❌ Удаление опций фильтра – Пользователи не могут нормально фильтровать
❌ Индексы базы данных – Незначительное улучшение, не решает основную причину
Оптимальное решение: Lazy-Load Slideout
Ключевая концепция: Загружайте фильтр ТОЛЬКО тогда, когда пользователь фактически открывает слайдаут.
✅ Страница загружается мгновенно (без обработки фильтра)
✅ Фильтр работает идеально, когда это необходимо
✅ Нет потраченных ресурсов сервера
✅ Идеально для ботов и обычных посетителей
✅ Сохраняет весь функционал фильтра
Реализация
Добавьте следующий код в тему вашего functions.php:
/**
* WOOF Lazy-Load Slideout Filter
* Loads filter only when user clicks to open slideout
* Solves performance issues with deep category hierarchies
*/
add_action('wp_footer', function () {
// Only on product category pages (optional - remove condition to show everywhere)
if (!is_product_category()) {
//return;
}
?>
<!-- Slideout Trigger Button -->
<div id="woof-slideout-trigger" style="position: fixed; right: 0; top: 50%; transform: translateY(-50%); z-index: 9999; cursor: pointer; background: #333; color: #fff; padding: 15px 10px; border-radius: 5px 0 0 5px; font-weight: bold; writing-mode: vertical-rl; text-orientation: mixed;">
FILTERS
</div>
<!-- Slideout Panel -->
<div id="woof-slideout-panel" style="position: fixed; right: -350px; top: 0; width: 350px; height: 100%; background: #fff; box-shadow: -2px 0 10px rgba(0,0,0,0.3); z-index: 9998; transition: right 0.3s ease; overflow-y: auto; padding: 20px;">
<!-- Close Button -->
<div style="text-align: right; margin-bottom: 15px;">
<span id="woof-slideout-close" style="cursor: pointer; font-size: 24px; font-weight: bold;">✖</span>
</div>
<!-- WOOF Filter with autohide - loads only on first click -->
<?php echo do_shortcode('[woof autohide=0 start_filtering_btn=1]'); ?>
</div>
<!-- Background Overlay -->
<div id="woof-slideout-overlay" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 9997; display: none;"></div>
<script>
jQuery(document).ready(function ($) {
var $trigger = $('#woof-slideout-trigger');
var $panel = $('#woof-slideout-panel');
var $overlay = $('#woof-slideout-overlay');
var $close = $('#woof-slideout-close');
var filterLoaded = false;
// Open slideout
$trigger.on('click', function () {
$panel.css('right', '0');
$overlay.fadeIn(300);
// Auto-trigger WOOF "Start Filtering" button on first open
if (!filterLoaded) {
setTimeout(function () {
var $woofBtn = $('.woof_start_filtering_btn');
if ($woofBtn.length) {
$woofBtn.trigger('click');
// Hide the button after triggering
$woofBtn.hide();
filterLoaded = true;
}
}, 500);
}
});
// Close slideout
function closeSlideout() {
$panel.css('right', '-350px');
$overlay.fadeOut(300);
}
$close.on('click', closeSlideout);
$overlay.on('click', closeSlideout);
});
</script>
<?php
}, 999);
Шаги настройки
- Отключите текущий слайдаут в настройках WOOF, если он включен
- Добавьте приведенный выше код to
functions.phpвашей активной темы - Оставьте эти настройки WOOF включенными:
- Кэшировать динамический пересчет: Да
- Кэшировать термины: Да
- Скрывать пустые термины: Да
- Динамический пересчет: Да
- Дополнительная настройка:
- Настроить ширину слайдаута: изменить
width: 350pxandright: -350px - Изменить положение кнопки: модифицировать
top: 50% - Настроить цвета: обновить
backgroundandcolorзначения - Сделать его работающим на всем сайте: удалить
if (!is_product_category())условие
- Настроить ширину слайдаута: изменить
Как это работает
- Загрузка страницы: Отображается только кнопка-триггер (без обработки фильтра)
- Пользователь нажимает кнопку: Открывается слайдаут, появляется наложение
- Только первый раз при открытии: JavaScript автоматически нажимает скрытую кнопку «Начать фильтрацию»
- Фильтр загружается: WOOF обрабатывает все запросы и отображает опции фильтра
- Последующие открытия: Фильтр уже загружен, открывается мгновенно
Реальные результаты
До:
- Загрузка страницы: 10-15 секунд (или таймаут 504)
- 500+ SQL-запросов на просмотр страницы
- Высокий показатель отказов
После:
- Загрузка страницы: < 2 секунд
- Фильтр загружается ~ за 3 секунды (только по запросу)
- ~50% снижение нагрузки на сервер (многие пользователи никогда не открывают фильтр)
Совместимость
✅ Работает со всеми версиями WOOF
✅ Совместимо с кешированием страниц (WP Rocket, LiteSpeed и т.д.)
✅ Дружественный к мобильным устройствам
✅ Работает с любой темой WordPress
Расширенная настройка
Соответствие стилю вашей темы:
/* Add to your theme's CSS */
#woof-slideout-trigger {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: 'Your Theme Font', sans-serif;
letter-spacing: 2px;
}
#woof-slideout-panel {
background: #f8f9fa;
font-family: 'Your Theme Font', sans-serif;
}
#woof-slideout-trigger:hover {
transform: translateY(-50%) scale(1.05);
}
Выдвижная панель слева:
Измените эти значения:
right: -350px → left: -350px
right: 0 → left: 0
right: -350px → left: -350px
Когда использовать это решение
Используйте выдвижную панель с ленивой загрузкой, когда:
- Категория имеет глубокую иерархию (3+ уровня)
- 500+ товаров в категории
- Требуется динамический пересчет
- Время загрузки страницы > 5 секунд
- Проблемы с таймаутом 504
Альтернатива для фильтра в боковой панели
Если вы предпочитаете боковую панель вместо выдвижной, используйте:
echo do_shortcode('[woof autohide=1 start_filtering_btn=1]');
Это создает кнопку «Начать фильтрацию» в вашей боковой панели, которая загружает фильтр по клику.
Это решение обеспечивает наилучший баланс между производительностью and функциональностью, гарантируя быструю загрузку страниц при сохранении полных возможностей фильтрации для пользователей, которым они необходимы.