Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Context-based getElementById is 1000 time slower than native getElementById. Do selector engines like sizzle use a cleverer strategy?

Tags:

javascript

dom

Being interested in building html chunks off-dom before to insert them in the dom, I have done some testing using dynatrace. I used bobince's method : Is there any way to find an element in a documentFragment?

I found it to be almost 1000 time slower (in IE7), which surprised me a lot.

Since the function is pretty basic, I was wondering about the strategy used by engines such as sizzle.

I would like to know if there is some more efficient ways to do context-based node selection ?

like image 720
Olivvv Avatar asked Jan 29 '10 22:01

Olivvv


1 Answers

Framework selector engines are generally evaluated right-hand-first, so I would expect a contextual ID selector to document.getElementById the ID and then check to see whether the results were in the context node by stepping up the parentNodes. This is reasonably fast, but it won't work for out-of-Document DOM trees like this example. Selector engines then would have to do it the desperately slow way, or not care (eg. Sizzle doesn't work with DocumentFragment).

There is a better way of getting the ID inside a fragment I've remembered since then, for browsers that implement Selectors-API (IE8, Firefox 3.5, Opera 10, Safari 3.1, Chrome 3). You can use querySelector to apply a CSS selector with the DocumentFragment as a context node, as the API requires DocumentFragment implements NodeSelector:

alert(frag.querySelector('#myId'))

This isn't quite as fast as getElementById, but it's loads better than the DOM version.

Unfortunately most frameworks that have Selectors-API optimisations won't use them in this case or any others with context nodes, because the way the context node works is different in querySelector[All] to how the frameworks traditionally implemented it, making them incompatible.

Selectors-API Level 2 proposes ‘scoped’ methods that behave like the traditional framework selectors... it'll be a while before that's usable, but we probably won't see optimised contextual selectors in the existing frameworks until then. I think this is a shame, as although the querySelector method of using the context node for filtering but not scoping is not quite as good, it's still pretty much usable for all the common cases.

like image 132
bobince Avatar answered Oct 15 '22 06:10

bobince