The context-sensitive getElementById is 1000 times slower than native getElementById. Can selector motors use a sticky strategy?

Being interested in creating html chunks off-dom, before I embed them in dom, I did some testing using dynatrace. I used the bobince method: Is there a way to find an element in a Fragment document?

I found that it was almost 1000 times slower (in IE7), which really surprised me.

Since the function is pretty simple, I was interested to learn about the strategy used by engines like sizzle.

I would like to know if there are more efficient ways to make a selection of node based on context?

+6
javascript dom
source share
2 answers

Wireframe selector mechanisms are generally evaluated on the right side, so I would expect the context identifier ID to be document.getElementById identifier, and then check if the results were in the context of the node by activating parentNode s. This is fast enough, but it will not work for documentless DOM trees, like this example. Selector engines then would have to do it in a desperately slow way or not care (for example, Sizzle does not work with DocumentFragment ).

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

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

It is not as fast as getElementById , but it loads better than the DOM version.

Unfortunately, most frameworks that have Selectors-API optimizations will not use them in this case or any other with context nodes, since the way the node context works is different from querySelector [ All ] in the way that they traditionally implement it by doing their incompatible.

API Selectors Level 2 offers “scope methods that behave like traditional frame selectors ... it will be a while before but we probably won't see optimized context selectors within the existing framework. I think it's a shame. because, despite the fact that the querySelector method of using the node context to filter, but not to determine the scope, is not so good, it is still very useful for all common cases.

+1
source share

If you don't mind temporarily pasting your document in the DOM ...

 function getElementFromFragById(frag, id) { var tempDiv = document.createElement("div"); tempDiv.style.display = "none"; tempDiv.appendChild(frag); document.body.appendChild(tempDiv); var elem = document.getElementById(id); document.body.removeChild(tempDiv); return document.getElementById(id) ? null : elem; //if the element still exists, we have a problem } 

This works reliably as long as your documentFragment does not contain elements with id that already exist in document , and you want to search by that identifier.

0
source share

All Articles