Somna
Somna

Reputation: 148

Which method for finding closest descendants with jQuery is more efficient?

The two methods below both accomplish the same task. They search for the descendants that match the selector, that are not nested in another match. I am trying to determine which of these two methods would be more efficient, but I'm not sure what the best way to calculate the performance difference between them is. Any ideas?

I am currently leaning towards the one I came up with (the first one) simply because it does not need to touch nodes that don't match the selector. However, if the nesting is too deep, the second one might end up touching less. If the performance difference is purely situational, is there a good check to determine which logic set to use?

function closestDescendants(selector, context)
{
    /// <summary>
    /// Similar but opposite to closest (ancestor), 
    /// Returns the descendants matching the selector, 
    /// but not their descendants.
    /// </summary>
    /// <param name="selector">The jQuery selector for the descendants.</param>
    /// <param name="context">The parent to search under.</param>
    if(!context)
    {
        context = document;
    }

    var $context = $(context);

    // Using find/filter/closest
    return $context
        .find(selector)
        .filter(function()
        {
            var $this = $(this);
            var $closest = $this.parent().closest(selector, $context);
            return !$closest.length || $context.is($closest);
        });
}

After writing the first method, I came across http://bugs.jquery.com/ticket/8263, which uses the logic below.

function closestDescendants(selector, context)
{
    /// <summary>
    /// Similar but opposite to closest (ancestor), 
    /// Returns the descendants matching the selector, 
    /// but not their descendants.
    /// </summary>
    /// <param name="selector">The jQuery selector for the descendants.</param>
    /// <param name="context">The parent to search under.</param>
    if(!context)
    {
        context = document;
    }

    var $context = $(context);

    var selection = [];
    var query = function($node)
    {
        $node.children().each(function()
        {
            var $this = $(this);
            if($this.is(selector))
            {
                selection.push(this);
            }
            else
            {
                query.call($this);
            }
        });
    };

    query.call($context);
    return this.pushStack(selection, "closestDown", selector);
}

Upvotes: 0

Views: 170

Answers (1)

bwitkowicz
bwitkowicz

Reputation: 754

Well, it will pretty much always depend on the scenario so there is no difinitive winner in terms of finding the most efficent descendant.

But in your case I would suggest wrapping your function call with console.time and see for yourself which one finishes faster.

console.time('My Benchmark');
closestDescendants(parameters);
console.timeEnd('My Benchmark');

This will print the time in miliseconds inside your console. Just make sure you are using Chrome or Firefox and don't use console.time on production environment (it doesn't work in IE and may throw an error).

Upvotes: 1

Related Questions