jQuery 中最快的 children() 或 find() 是啥?

Posted

技术标签:

【中文标题】jQuery 中最快的 children() 或 find() 是啥?【英文标题】:What is fastest children() or find() in jQuery?jQuery 中最快的 children() 或 find() 是什么? 【发布时间】:2010-10-13 11:27:08 【问题描述】:

要在 jQuery 中选择子节点,可以使用 children(),也可以使用 find()。

例如:

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

给出与以下相同的结果:

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

现在,哪个选项最快或首选,为什么?

【问题讨论】:

.find().children() 不一样。后者仅沿 DOM 树向下移动一层,就像子选择器一样。 @Timothy003 你描述错了,前者是单层往下走,不是后者 @DipeshRana 的“后者”适用于 Timothy003 自己的句子,而不是问题。 感谢您提出这个问题。在许多情况下,性能差异是微不足道的,但文档实际上并没有提到这两种方法的实现方式不同!为了最佳实践,很高兴知道find() 几乎总是更快。 这就是为什么我从不喜欢英语中的“前者”或“后者”结构。直接说你指的是哪一个。嘘。 【参考方案1】:

children() 只查看节点的直接子节点,而find() 遍历节点下方的整个 DOM,因此children() 应该 在等效实现的情况下更快。但是,find() 使用 native 浏览器方法,而 children() 使用在浏览器中解释的 javascript。在我的实验中,典型情况下的性能差异不大。

使用哪个取决于您是只想考虑DOM中的直接后代还是该节点下的所有节点,即根据您想要的结果选择合适的方法,而不是方法的速度。如果性能确实是一个问题,那么尝试找到最佳解决方案并使用它(或在此处查看其他答案中的一些基准)。

【讨论】:

当然可以,但是如果父元素只有子节点会发生什么?我将对此进行一些分析。 children 与 find 的性能取决于浏览器以及您搜索的 DOM 子树的复杂程度。在现代浏览器 find() 内部使用 querySelectorAll 可以轻松地在复杂选择器和中小型 DOM 子树上优于 children()。 有助于提供一些实验的定量结果。 对我来说,在所有层级嵌套在 5 到 20 之间的测试中,find() 总是优于 children()。 (在 Google Chrome 54 中测试)我的预期正好相反。所以从现在开始,我将采取简单的方法找到(...)我的元素,而不是通过 children().children().children()...【参考方案2】:

jsPerf test 表明 find() 更快。我创建了一个more thorough test,它看起来仍然好像 find() 胜过 children()。

更新:根据 tvanfosson 的评论,我创建了 another test case 16 级嵌套。 find() 只是在查找所有可能的 div 时速度较慢,但​​ find() 在选择第一级 div 时仍然优于 children()。

当有超过 100 层嵌套和大约 4000 多个 div 供 find() 遍历时,children() 开始优于 find()。这是一个基本的测试用例,但我仍然认为 find() 在大多数情况下比 children() 快。

我在 Chrome 开发者工具中浏览了 jQuery 代码,发现 children() 在内部调用了兄弟()、filter(),并且比 find() 执行了更多的正则表达式。

find() 和 children() 满足不同的需求,但是在 find() 和 children() 输出相同结果的情况下,我建议使用 find()。

【讨论】:

好像children使用dom遍历方法,find使用selector api,速度更快。 相当退化的测试用例,因为你只有一层嵌套。如果您想要一般情况,则必须设置一些任意嵌套深度并检查性能,因为 find() 遍历的树比 children() 更深。 如果您正在检查特定的单数子元素(例如 event.target)是否在特定的 dom 元素中(例如 $('.navbar')),那么 $.contains(this, event .target) 是迄今为止最快的(8,433,609/秒,而最快的 jquery 搜索为 140k)。 jsperf.com/child-is-in-parent【参考方案3】:

这里是a link,您可以运行一个性能测试。 find() 实际上比 children() 快大约 2 倍。

【讨论】:

$.contains(document.getElementById('list'), $('.test')[0]) 是 8,433,609/秒。如果您有特定元素并且只想知道 B 是否在 A 中,那么这是最好的。 jsperf.com/child-is-in-parent 不错的测试。请注意,如果您执行 var $test = $list.find('.test'); 之类的操作,其中 $list 是 jQuery 对象,它会更快。 jsperf.com/jquery-selectors-context/101【参考方案4】:

这些不一定会给出相同的结果:@987654321@ 将获得任何后代节点,而@987654322@ 只会获得匹配的直系子节点

在某一时刻,find() 的速度要慢得多,因为它必须搜索每个可能匹配的后代节点,而不仅仅是直接子节点。然而,这不再是真的; find() 使用本机浏览器方法,速度更快。

【讨论】:

不根据其他答案哈哈:p。只有当你有一个非常、非常、非常大的 DOM 树时.. @Camou 这个答案是四年前的。 find() 当时的速度要慢得多! @camou 说表演部分是“不是根据其他答案”。这个答案的第一段是准确的。【参考方案5】:

没有其他答案涉及使用.children().find(">")搜索父元素的直接子元素的情况。所以,我创建了一个jsPerf test to find out,使用三种不同的方式来区分孩子。

碰巧,即使使用额外的 ">" 选择器,.find() 仍然比.children()很多;在我的系统上,是 10 倍。

所以,在我看来,似乎根本没有太多理由使用.children() 的过滤机制。

【讨论】:

感谢您的评论!我想知道 jQuery 是否应该切换到让 .children(x) 成为 .find(">" + x) 的别名,尽管我可能没有想到其他复杂情况。 这似乎是最合适的比较。谢谢!【参考方案6】:

find()children() 方法都用于过滤匹配元素的子元素,除了前者是向下移动任何级别,后者是向下移动一个级别。

为了简化:

    find() - 搜索匹配元素的孩子、孙子、曾孙……所有级别。 children() – 仅搜索匹配元素的子元素(向下一层)。

【讨论】:

【参考方案7】:

很抱歉,我自己的经验与这里的大多数答案都不匹配,所以我认为在这里分享它并建议人们针对自己的使用环境进行自己的测试很有趣。

通过在我的脚本的多个位置将$(...).find() 替换为$(...).children(),我刚刚获得了大约40% 的性能。

项目的实际嵌套非常低(最多 3 层),尽管如此,children() 显然效率更高。

两者都被调用了数千次以检索网格中的信息(由数千个 组成)。目的主要是根据单元格内容中的几件事对单元格/列/行应用一些样式。

使用 Firefox,在替换 find() 之前,网格的加载时间在 2100 到 2400 毫秒之间。在使用 children() 进行更改后,它减少到 1300 到 1500 毫秒之间(因此减少了 30% 到 40%)。

但是,不幸的是,对于 Chrome,它并没有那么令人信服:Chrome 处理完全相同的事情要慢得多(8 秒),而且我看不出在此更改前后有任何明显的性能差异。

【讨论】:

以上是关于jQuery 中最快的 children() 或 find() 是啥?的主要内容,如果未能解决你的问题,请参考以下文章

jquery 在IE浏览器中无法使用find()或children()遍历xml数据

jquery如何获取第一个或最后一个子元素

jquery 和 CSS 中最快的选择器方法 - ID 与否?

jquery如何获取第一个或最后一个子元素

常用jQuery方法

jQuery——选择器效率