Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parent(), faster alternative?

I am working with a dashboard of divs and each div it has a tree of which the buttons are. Every time I have to know which the id of that div is so I am using parent() alot.

Mostly I am doing $(this).parent().parent().parent() to find the ID of div so I can set variables to it. The app is based on the id's of each div.

Is it consider slow to use parent() up to 3 times but pretty much on every function?

Is there any other alternative?

I am looking for something like benchmarks-style which shows what's faster.

Here is an example of the tree:

<div id="6179827893" class="dashdiv">
   <div class="buttons">
     <li><a href="#" class="btn1">Button 1</a></li>
     <li><a href="#" class="btn2">Button 2</a></li>
     <li><a href="#" class="btn3">Button 3</a></li>
     <li><a href="#" class="btn4">Button 4</a></li>
     <li><a href="#" class="btn5">Button 5</a></li>
     <li><a href="#" class="btn6">Button 6</a></li>
   </div>
   <div class="dashcontent">

    ....

   </div>
</div>
like image 742
jQuerybeast Avatar asked Jan 09 '12 13:01

jQuerybeast


3 Answers

You've got a few options to achieve the same effect.

Benchmark: http://jsperf.com/parents-method. According to this benchmark, my method is roughly 100x faster than your method.

Method (see below) : Operations per second (higher is better)
parentNode3x       : 4447k
$(parentNode3x)    :  204K
$().closest        :   35k
$().parents        :    9k
$().parent()3x     :   44k

// Likely the fastest way, because no overhead of jQuery is involved.
var id = this.parentNode.parentNode.parentNode.id;

// Alternative methods to select the 3rd parent:
$(this.parentNode.parentNode.parentNode) // Native DOM, wrapped in jQuery

// Slowpokes
$(this).closest('.dashdiv')              // Hmm.
$(this).parents('.dashdiv:first')        // Hmm...
like image 196
Rob W Avatar answered Nov 09 '22 17:11

Rob W


You might be better off using .closest(), like this: $(this).closest('.dashdiv')

It's not any faster from an engine's point of view, since you're still looping up through the DOM layers, but it's more clear to a newcomer as well as shorter code.

COMMENTARY

If it's pure speed you're after, you might as well skip jQuery entirely and use node.parentNode instead. But this is getting into niggly issues of counting cycles, and I think it's an academic one.

If you're writing high-performance code for major production, like a commercial search engine or webmail provider, then counting cycles is important because any small optimization gets multiplied thousands of times. With all due respect, I doubt you're writing that kind of code.

If you're writing something that's going to be hit by a few people at a time, at most, then small optimizations are an intellectual exercise that won't affect results in any noticable way. You'd have to improve your code's efficiency by hundreds of milliseconds before any user would even begin to notice, and this code isn't going to do that.

Instead, it's far more important to think about the next developer who will be looking at your code. For that developer, it's important to have clear, well-written code that immediately communicates what it's doing. Eye-blurring chains of methods like parent().parent().parent() can obscure and confuse other developers, to say nothing of node.parentNode.parentNode.parentNode

-- which is why .closest() was created in the first place. It's clear, concise, and not noticably less efficient than the chains it replaces. 999 times out of a thousand, it's the way you ought to go.

like image 25
Blazemonger Avatar answered Nov 09 '22 18:11

Blazemonger


First, don't optimise prematurely. If it's not causing a problem (and test thoroughly by all means, across a range of platforms) then don't worry about it.

There is a possible optimisation: use native DOM properties:

var id = this.parentNode.parentNode.parentNode.id;

Note that the nicest jQuery way to do this (which will be slower, but that may not be a problem) is with closest:

$(this).closest('div.dashdiv').prop('id');
like image 2
lonesomeday Avatar answered Nov 09 '22 18:11

lonesomeday