335

To select a child node in jQuery one can use children() but also find().

For example:

$(this).children('.foo');

gives the same result as:

$(this).find('.foo');

Now, which option is fastest or preferred and why?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
bart
  • 14,958
  • 21
  • 75
  • 105
  • 31
    `.find()` and `.children()` are not the same. The latter only travels a single level down the DOM tree, like a child selector. – Timothy003 Mar 25 '12 at 15:46
  • 1
    @Timothy003 You have described it wrong, the former one travels single level down not the latter – Dipesh Rana Jun 08 '15 at 12:32
  • 6
    @DipeshRana the 'latter' applied to Timothy003's own sentence, not the question. – bhootjb Jun 17 '15 at 15:25
  • 1
    Thanks for bringing this issue up. In many cases the performance difference is trivial, but the docs don't actually mention that these two methods are implemented differently! For the sake of best practices, it's good to know that `find()` is nearly always faster. – Steve Benner May 16 '19 at 08:23
  • That's why I never liked the "the former" or "the latter" construction in English. Just say which one you mean. Sheesh. – Chris Walker Apr 10 '20 at 16:38

7 Answers7

433

children() only looks at the immediate children of the node, while find() traverses the entire DOM below the node, so children() should be faster given equivalent implementations. However, find() uses native browser methods, while children() uses JavaScript interpreted in the browser. In my experiments there isn't much performance difference in typical cases.

Which to use depends on whether you only want to consider the immediate descendants or all nodes below this one in the DOM, i.e., choose the appropriate method based on the results you desire, not the speed of the method. If performance is truly an issue, then experiment to find the best solution and use that (or see some of the benchmarks in the other answers here).

Amaury
  • 126
  • 10
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • 9
    Sure, but what happens if the parent element only has child nodes? I'm going to do some profiling on this. – jason Jul 17 '10 at 22:01
  • 11
    The performance of children vs find depends on the browser an on how complex the DOM-subtree is your searching. On modern browers find() internally uses querySelectorAll which easily can outperform children() in complex selector and on small to moderate DOM subtree. – LeJared Nov 02 '12 at 11:39
  • Would help to provide some quantitative results of your experiments. – Luke Aug 19 '15 at 14:13
  • For me in all tests with hierarchy nestings between 5 and 20 find() always outperformed children(). (tested in Google Chrome 54) I expected the opposite. So from now on, i'll take the easy way and find(...) my elements instead of traversing them down via children().children().children()... – Ruwen Sep 30 '16 at 07:34
183

This jsPerf test suggests that find() is faster. I created a more thorough test, and it still looks as though find() outperforms children().

Update: As per tvanfosson's comment, I created another test case with 16 levels of nesting. find() is only slower when finding all possible divs, but find() still outperforms children() when selecting the first level of divs.

children() begins to outperform find() when there are over 100 levels of nesting and around 4000+ divs for find() to traverse. It's a rudimentary test case, but I still think that find() is faster than children() in most cases.

I stepped through the jQuery code in Chrome Developer Tools and noticed that children() internally makes calls to sibling(), filter(), and goes through a few more regexes than find() does.

find() and children() fulfill different needs, but in the cases where find() and children() would output the same result, I would recommend using find().

JR.
  • 5,840
  • 9
  • 31
  • 34
  • 4
    It seems that children uses dom traversal methods and find uses the selector api, which is faster. – topek Oct 07 '11 at 20:29
  • 4
    Pretty degenerate test case since you only have one level of nesting. If you want the general case you'll have to set up some arbitrary nesting depths and check the performance as find() traverses deeper trees than children(). – tvanfosson Oct 31 '11 at 22:15
  • If you are checking if a specific singular child element (eg. event.target) is in a specific dom element (eg. $('.navbar')) then $.contains(this, event.target) is by far the fastest (8,433,609/second vs 140k for the fastest jquery search). http://jsperf.com/child-is-in-parent – Chris Sattinger Sep 06 '15 at 11:36
91

Here is a link that has a performance test you can run. find() is actually about 2 times faster than children().

Chrome on OSX10.7.6

SharpC
  • 6,974
  • 4
  • 45
  • 40
mactive
  • 1,560
  • 11
  • 7
  • $.contains(document.getElementById('list'), $('.test')[0]) is 8,433,609/second. If you have specific elements and just want to know if B is in A then this is best. http://jsperf.com/child-is-in-parent – Chris Sattinger Sep 06 '15 at 11:40
  • Nice test. Note that it can be even faster if you do something like `var $test = $list.find('.test');` where $list is jQuery object. http://jsperf.com/jquery-selectors-context/101 – Maciej Krawczyk Sep 07 '15 at 21:23
26

Those won't necessarily give the same result: find() will get you any descendant node, whereas children() will only get you immediate children that match.

At one point, find() was a lot slower since it had to search for every descendant node that could be a match, and not just immediate children. However, this is no longer true; find() is much quicker due to using native browser methods.

Craig Walker
  • 49,871
  • 54
  • 152
  • 212
John Feminella
  • 303,634
  • 46
  • 339
  • 357
16

None of the other answers dealt with the case of using .children() or .find(">") to only search for immediate children of a parent element. So, I created a jsPerf test to find out, using three different ways to distinguish children.

As it happens, even when using the extra ">" selector, .find() is still a lot faster than .children(); on my system, 10x so.

So, from my perspective, there does not appear to be much reason to use the filtering mechanism of .children() at all.

Craig Walker
  • 49,871
  • 54
  • 152
  • 212
4

Both find() and children() methods are used to filter the child of the matched elements, except the former is travels any level down, the latter is travels a single level down.

To simplify:

  1. find() – search through the matched elements’ child, grandchild, great-grandchild... all levels down.
  2. children() – search through the matched elements’ child only (single level down).
SharpC
  • 6,974
  • 4
  • 45
  • 40
Naresh Kumar
  • 345
  • 3
  • 6
1

I'm sorry but my own experience will not match with most of the answers here so I think it's interesting to share it here and suggest people to do their own tests for their own usage context.

I have just gained approximatively 40% performance by replacing in several places of my script $(...).find() by $(...).children().

The actual nesting of items was really low (max 3 levels), and despite this children() is clearly much more efficient.

Both were called thousands of times to retrieve informations in a grid (made of thousands of ). The purpose is to mainly to apply some styling to cells / columns / rows depending of several things in the cell content.

With Firefox, before to replace find(), load time for the grid was between 2100 and 2400ms. After the change with children(), it was reduced to something between 1300 and 1500ms (so between 30% and 40% less).

However, with Chrome, it's not so convincing unfortunately : Chrome is much slower (8s) to process exactly the same thing, and I don't see any obvious performance difference before and after this change with it.

AFract
  • 8,868
  • 6
  • 48
  • 70