jQuery优化选择器

Mic*_*ael 7 optimization jquery

我想知道有一天当你在jQuery中输入你的选择器时,如果你指定你的选择器非常具体或非常松散,它会对性能产生影响.

例如

$('$myId .someElement')
Run Code Online (Sandbox Code Playgroud)

要么

$('table#myId > tbody > tr > td > div.someElement');
Run Code Online (Sandbox Code Playgroud)

第二个选项是否会更快或者差异是否可以忽略,比如当.each()你需要一遍又一遍地找到相同的元素时.

Fel*_*ing 5

更新2:

在这里总结一些其他评论.答案取决于它.

jQuery的选择器引擎Sizzle以与CSS相同的方式评估选择器:从右到左.所以一般来说,最好是在右侧非常具体,在左侧不太具体.

但它还取决于HTML的结构以及您想要查找的元素的分散程度.

所以,如果你有

                         a
                         |
                        ...
                         |
                         b
                 -----------------
                 |               |
d d d c c c c c   c c c c c c c c   c c c c c c
Run Code Online (Sandbox Code Playgroud)

然后更具体更快$('a b > c'),因为你早期减少元素集,b > c而不必检查a每个元素的继承c.

如果你有的话

                         a
                         |
                        ...
                         |
                         b
                 -----------------
                 |               |
e e e e e e e e   d d c c c c c c   e e e e e e
Run Code Online (Sandbox Code Playgroud)

然后$('a c')会更快,因为选择器更简单,在这种情况下测试c成为孩子b是多余的(当然你甚至可以这样做$('c')).


原始答案:

无论哪一个更快,如果您必须反复访问元素,请存储对它的引用:

var $element = $('#myId .someElement');

$('some other selector').each(function() {
    // access $element here
});
Run Code Online (Sandbox Code Playgroud)

第一个选择器似乎更快(在Chrome 8中).

在较新的浏览器(支持querySelectorAll)中,差异可能不如不支持它的浏览器那么大.

更新:

我认为这主要取决于jQuery可以使用多少内置方法.因此,假设querySelector*不可用,可以将第一个选择器转换为

document.getElementById('myId')[0].getElementsByClassName('someElement')
Run Code Online (Sandbox Code Playgroud)

对于第二个选择器,jQuery必须另外检查一个元素是否确实是一个孩子.即,还涉及更多处理.


ifa*_*our 4

我会选择:

$('.someElement', '#myId')
Run Code Online (Sandbox Code Playgroud)

由于 getElementById 是最快的选择器操作,因此您首先要过滤内容,然后搜索类。此外,选择器越少,选择速度就越快(取决于是否使用后代选择器 - 检查注释!)。 基于@Felix测试用例进行 测试。

编辑:所以为了增强这个答案。基于 jQuery文档

默认情况下,选择器在 DOM 中从文档根开始执行搜索。但是,可以通过使用 $() 函数的可选第二个参数来为搜索提供替代上下文。

因此,当您提供第二个参数(上下文)时,jQuery 将首先搜索该元素,然后在其中搜索,因此它将被翻译为:

$('.someElement', '#myId')
Run Code Online (Sandbox Code Playgroud)

到:

$('#myId').find('.someElement')
Run Code Online (Sandbox Code Playgroud)

现在的技巧是,尝试找到实际保存 ID 的元素的最接近的容器并将其作为context,因为 ID 选择是最快的。现在你会说,为什么不使用第二个已经翻译的,因为我实际上并不太关心,因为第一个更干净而且速度也慢不了多少:

                    $('.someElement', '#myId')                  $('#myId').find('.someElement')
Chrome 8.0.552              36,527                                      37,400
Firefox 3.6.13              17,632                                      19,155
Run Code Online (Sandbox Code Playgroud)