<p id="all">
<p class="class1">one</p>
<p class="class1">two</p>
<p class="class1">three</p>
<p class="class1">four</p>
<p class="class2">five</p>
</p>
通过实验发现$("#all").find(".class2")
要比$("#all .class2")
性能好,为什么呢?jQuery
和CSS
都用的是Sizzle
选择器引擎,他的解析方式是从右向左。也有说如果最左边指定了id
,就会先取id
,这时是不是就会从左向右匹配了?
大家讲道理2017-04-17 11:08:43
I haven’t seen the specific implementation, but the former obviously matches from left to right, and if the latter does the same, the performance should be the same. Since the former performs better, it is obvious that the latter should be from right to left.
You can consider doing another test:
<p id="all">
<span class="class1">one</p>
<span class="class1">two</p>
<span class="class1">three</p>
<span class="class1">four</p>
<p class="class2">five</p>
</p>
Test $("#all").find("p.class2")
and $("#all p.class2")
阿神2017-04-17 11:08:43
The main job of the Sizzle selector engine is to be upwardly compatible with the querySelectorAll API. If all browsers support this API, then there is no need for Sizzle to exist.
The sizzle selector generally matches from right to left (when there is no position pseudo-class). Sizzle does not completely match from right to left. If there is an #id selector on the leftmost side of the selector expression, it will be matched first. Query on the far left and use it as the execution context for the next step, ultimately achieving the purpose of reducing the context,
$("#all.class2") This sentence will first match all #all elements, and then use them as context to search for .class2
$("#all").find(".class2") Here, #all is matched first, and then the matching .class2 is found;
If you use sizzle, the performance of the two should be similar. However, in browsers that support querySelectorAll, the former may not use the sizzle engine, but directly call the native one, causing the two to be different. All my guesses lead to the result of the topic