Оптимизация производительности: ленивая загрузка slideout для больших иерархий категорий
Когда у вас есть родительская категория с:
- Большим количеством товаров (500-1000+)
- Глубокой иерархией категорий (несколько уровней подкатегорий)
- Включённым Dynamic Recount
Фильтр товаров может генерировать сотни SQL-запросов при каждой загрузке страницы, даже если пользователь никогда не использует фильтр. Это приводит к:
- Медленной загрузке страницы (10+ секунд)
- Ошибкам 504 Gateway Timeout
- Высокой нагрузке на сервер
- Плохому пользовательскому опыту
Почему это происходит
При включённом Dynamic Recount WOOF должен:
- Рекурсивно обрабатывать все дочерние категории
- Выполнять SQL-запросы для каждого термина, чтобы подсчитать товары
- Вычислять количество с учётом контекста текущей категории
Пример: Категория “Sunglasses” с подкатегориями (Men → Women → Shapes → Brands) создаёт огромную нагрузку запросами.
Традиционные решения (недостаточно)
❌ Скрытие slideout правилами CSS/display — Фильтр всё равно обрабатывается на сервере
❌ Отключение Dynamic Recount — Теряется важная функциональность
❌ Удаление опций фильтра — Пользователи не могут правильно фильтровать
❌ Индексы базы данных — Небольшое улучшение, не решает корневую причину
Оптимальное решение: ленивая загрузка slideout
Ключевая идея: Загружать фильтр ТОЛЬКО когда пользователь действительно открывает 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);
Шаги настройки
- Отключите текущий slideout в настройках WOOF, если он включён
- Добавьте код выше в
functions.phpвашей активной темы - Оставьте включёнными следующие настройки WOOF:
- Cache dynamic recount: Yes
- Cache terms: Yes
- Hide empty terms: Yes
- Dynamic Recount: Yes
- Опциональная настройка:
- Настройте ширину slideout: измените
width: 350pxиright: -350px - Измените положение кнопки: измените
top: 50% - Настройте цвета: обновите значения
backgroundиcolor - Чтобы работало по всему сайту: удалите условие
if (!is_product_category())
- Настройте ширину slideout: измените
Как это работает
- Загрузка страницы: Рендерится только кнопка-триггер (без обработки фильтра)
- Пользователь нажимает кнопку: Slideout открывается, появляется оверлей
- Только при первом открытии: JavaScript автоматически нажимает скрытую кнопку “Start Filtering”
- Фильтр загружается: 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);
}
Slideout слева:
Измените эти значения:
right: -350px → left: -350px
right: 0 → left: 0
right: -350px → left: -350px
Когда использовать это решение
Используйте ленивую загрузку slideout, когда:
- У категории глубокая иерархия (3+ уровня)
- 500+ товаров в категории
- Требуется Dynamic Recount
- Время загрузки страницы > 5 секунд
- Возникают таймауты 504
Альтернатива для фильтра в сайдбаре
Если предпочитаете сайдбар вместо slideout, используйте:
echo do_shortcode('[woof autohide=1 start_filtering_btn=1]');
Это создаёт кнопку “Start Filtering” в сайдбаре, которая загружает фильтр по нажатию.
Это решение обеспечивает наилучший баланс между производительностью и функциональностью, гарантируя быструю загрузку страниц при сохранении полных возможностей фильтрации для тех пользователей, которым они нужны.