HUSKY - WooCommerce Products Filter Professional

Performance Optimization: Lazy-Load Slideout for Large Category Hierarchies

When you have a parent category with:

  • Large number of products (500-1000+)
  • Deep category hierarchy (multiple levels of subcategories)
  • Dynamic Recount enabled

Product filter could generate hundreds of SQL queries on every page load, even if the user never uses the filter. This causes:

  • Slow page loading (10+ seconds)
  • 504 Gateway Timeout errors
  • High server load
  • Poor user experience

Why This Happens

With Dynamic Recount enabled, WOOF must:

  1. Recursively process all child categories
  2. Execute SQL queries for each term to count products
  3. Calculate counts considering current category context

Example: A “Sunglasses” category with subcategories (Men → Women → Shapes → Brands) generates massive query load.

Traditional Solutions (Not Enough)

Hiding slideout with CSS/display rules – Filter still processes on server
Disabling Dynamic Recount – Loses important functionality
Removing filter options – Users can’t filter properly
Database indexes – Minor improvement, doesn’t solve root cause

The Optimal Solution: Lazy-Load Slideout

Key Concept: Load the filter ONLY when user actually opens the slideout.

✅ Page loads instantly (no filter processing)
✅ Filter works perfectly when needed
✅ No wasted server resources
✅ Perfect for bots and casual browsers
✅ Keeps all filter functionality intact

Implementation

Add next code to your theme’s 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);

Configuration Steps

  1. Disable your current slideout in WOOF settings if it enabled
  2. Add the code above to functions.php of your active theme
  3. Keep these WOOF settings enabled:
    • Cache dynamic recount: Yes
    • Cache terms: Yes
    • Hide empty terms: Yes
    • Dynamic Recount: Yes
  4. Optional customization:
    • Adjust slideout width: change width: 350px and right: -350px
    • Change button position: modify top: 50%
    • Customize colors: update background and color values
    • Make it work site-wide: remove the if (!is_product_category()) condition

How It Works

  1. Page loads: Only the trigger button renders (no filter processing)
  2. User clicks button: Slideout opens, overlay appears
  3. First open only: JavaScript automatically clicks the hidden “Start Filtering” button
  4. Filter loads: WOOF processes all queries and displays filter options
  5. Subsequent opens: Filter is already loaded, opens instantly

Real-World Results

Before:

  • Page load: 10-15 seconds (or 504 timeout)
  • 500+ SQL queries per page view
  • High bounce rate

After:

  • Page load: < 2 seconds
  • Filter loads in ~3 seconds (only when requested)
  • ~50% reduction in server load (many users never open filter)

Compatibility

✅ Works with all WOOF versions
✅ Compatible with page caching (WP Rocket, LiteSpeed, etc.)
✅ Mobile-friendly
✅ Works with any WordPress theme

Advanced Customization

Match your theme styling:

/* 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);
}

Left-side slideout:

Change these values:

right: -350px  →  left: -350px
right: 0       →  left: 0
right: -350px  →  left: -350px

When to Use This Solution

Use lazy-load slideout when:

  • Category has deep hierarchy (3+ levels)
  • 500+ products in category
  • Dynamic Recount is required
  • Page load time > 5 seconds
  • Experiencing 504 timeouts

Alternative for Sidebar Filter

If you prefer sidebar instead of slideout, use:

echo do_shortcode('[woof autohide=1 start_filtering_btn=1]');

This creates a “Start Filtering” button in your sidebar that loads the filter on click.


This solution provides the best balance between performance and functionality, ensuring fast page loads while maintaining full filtering capabilities for users who need them.

Ref: https://pluginus.net/support/topic/performance-issue-504-timeouts-on-parent-category-with-deep-hierarchy-flatsome-theme/

 


Troubles? Ask for Support!