Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slow performance with jQuery selector

I'm rendering over 600 forms in an MVC format (php Codeigniter). Each one of these forms has a button labeled "More Options". When you click this button - a hidden div, located in the same parent element, is toggled, displaying more input fields and data. The problem is that the sibling toggle is quick in console, but when I click the actual button, it takes very long to trigger.

Using id's is the recommended fix, but it is slightly impractical when I have this many div elements to go through.

Here is my js file

jQuery(document.ready(function(){
    jQuery("form >button[name='more_data'].meta_button").click( function(){  
        jQuery(this).siblings("div.meta").toggle("fast");
    });
});

Here is the structure (there are 650 of these div's, with more to come)

<div>
    <li id="bCIya8DZyr4idseJe5cbLA" class="even">
        <form action="url" method="post" accept-charset="utf-8">
            <div class="space_name"></div>
            <button name="more_data" type="button" class="meta_button">More Options</button>
            <input type="submit" name="Submit" value="Submit">
            <div class="meta" style="overflow: hidden; display: block;">
                <div class="meta_block">Set Estimates:
                    <div class="input_estimate">1:
                        <input type="number" name="estimate_1" value="" id="estimate_1" class="estimate">
                    </div>
                    <div class="input_estimate">2:
                        <input type="number" name="estimate_2" value="" id="estimate_2" class="estimate">
                    </div>
                    <div class="input_estimate">3:
                        <input type="number" name="estimate_3" value="" id="estimate_3" class="estimate">
                    </div>
                </div>
            </div>
        </form>
    </li>
</div>

Note: I'm running jQuery 1.7.2

like image 448
Fuhton Avatar asked Oct 22 '22 14:10

Fuhton


1 Answers

Don't use a delegate

Using a delegate (.on() with a selector) like @jrummell suggested is faster when you have multiple event listeners, because you reduce the number of listeners to one.

Simpler selector using a class

So in this case though I would recommend using a simpler selector:

$(function(){
    $('.meta_button').on('click', function(){
        $(this).siblings('div.meta').toggle('fast');
    });
});

This way you have quite simpler selector and less checks when a click is triggered, because there is no delegate. Also the clicks on other elements in the forms are not captured.

Animations slow things down

An animation could slow things down. An animation which is performed over multiple elements simultaneously even more.

Try moving all div.meta elements in a single parent and applying animation only on that single element.

You could also remove the animation entirely by just using toggle() (the comment about the multiple items is still valid in this case).

Example:

$(function(){
    $('.meta_button').on('click', function(){
        $(this).parent().find('.meta_holder').toggle();
        // OR
        // $(this).next('.meta_holder').toggle();
    });
});
like image 198
Haralan Dobrev Avatar answered Oct 28 '22 00:10

Haralan Dobrev