What is the fastest way to get the dom element?

I am customizing my code to my code, and I am surprised to find that the bottleneck is not the dom node insert, but the choice.

This is fast:

var row = jquery(rowHTML).appendTo(oThis.parentTable); 

but subsequent retrieval of the item inside the "string" is slow:

 var checkbox = jquery(".checkbox input", row); 

I need to check the box on each line so that I can bind an event handler to it. By selecting this check box, ALMOST 10X AS SLOW inserts the entire parent row.

What am I doing wrong here?

+6
javascript jquery dom
source share
7 answers

DOM manipulation uses its own functions to perform simple operations. Browser providers optimize them. You are building a string from HTML. Internally, jQuery uses .innerHTML to build a collection, which is then embedded in the mega-fast browser parser.

The choice is slow compared to the fact that the JS code must periodically iterate over the DOM. Newer browsers have their own selection processing, which provides significant acceleration for selector-based JS. Over time, this will be a problem.

This is how the query is broken, $(".checkbox input", row) :

  • row.getElementsByTagName('*');
  • for a loop through each returned element (all elements inside the string) and test elements[i].className with /(\s|^)checkbox(\s|$)/ .
  • for the loop all the remaining elements and collect matched[i].getElementsByTagName('input');
  • unique ultimate collection.

This is different from jQuery 1.3, because the engine moves the selector the other way around, starting with getting all the input elements and then testing the parent elements.

Remember that JS selectors implement much more CSS selector specifications than can actually be used with CSS (or implemented by current browsers). Using this and knowledge of the engines, we can optimize the selector, which can be optimized in several ways:

If you know the type of the .checkbox element:

 $("td.checkbox input", row); 

This is faster for the filter first for the type and then for the class only for these matches. This does not apply to a very small subset of elements, but it is almost never applied in practice.

The single class test is the slowest of the usual selectors that actually use .

Simplified Choice:

 $("input[type=checkbox]", row); 

One cycle is faster than two cycles. It only finds the input elements and then directly filters them by attribute type. Since sub / children are never used, unique ones can also be skipped (and smart mechanisms will try to do this because unique ones are slow).

More direct selector:

 $("td:first.checkbox input", row); 

A more complex selector can be faster if it is more direct (YMMV).

If possible, move the search context to the table level:

By this I mean that instead of iterating over the lines and looking for a flag in each of them, leave them alone until the loop is selected, and then select them all at a time:

 $("tr td:first.checkbox input", table); 

The point of view is to eliminate the overhead when starting the selector motor multiple times, but instead do it all in one direction. This is presented here for completeness, and not for something that, I think, will bring tremendous acceleration.

Do not choose:

Build a string of bits, assigning events as you move.

 var row = $( '<tr></tr>' ); var cell = $( '<td class="checkbox"></td>' ).appendTo( row ); $( '<input type="checkbox" name="..."/>' ).appendTo( cell ).click(/* ... */); 

This may not be possible for reasons of Ajax or other templates out of your control. Also, speed may not be worth turning your code into such a mess, but sometimes it may make sense.

Or, if none of them work for you or return too high a profit, it may be time to completely rethink the method. You can assign an event listener above the tree and capture events there instead of an instance for each element:

 $('table').change(function(e){ // you may want a faster check... if ( $(e.target).is('input[type=checkbox]') ) { // do some stuff ... } }); 

This way you are not doing anything unless the user requests it. The fastest.: -)

+13
source share
 var checkbox = jquery(".checkbox input", row); 

This is moving around the tree to find this flag. You could speed it up by changing the selector to an identifier that can use the getElementById functionality for browsers.

 var checkbox = jquery("#checkbox input", row); 

You can also use your string as a starting point for finding the DOM, as in the following example. Now you have not yet parsed the entire DOM tree to find a consistent element.

 var row = jquery(rowHTML).appendTo(oThis.parentTable); row.children(".checkbox input"); 
+2
source share

Use event delegation and add one handler to the parent element, not to the flags themselves.

jQuery supports this through the live() function.

+2
source share

Try putting the class name in the input field. It may be faster.

The reason for this is because your code goes through all the .checkbox classes, tries to find the input child of this element, and returns it. I think this may be your culprit.

Just by looking at all the elements with a class that has an input field, you can see the acceleration.

+1
source share

Try using Sly , it focuses on performance.

+1
source share

If you are looking for performance, jQuery selectors are very slow. In this example, he needs to check the complete DOM tree and check CSS classes, etc., to find the matching nodes.

Significantly faster to use your own DOM methods. Here are some interesting comparisons of library performance:

http://ajaxian.com/archives/taskspeed-more-benchmarks-for-the-libraries-and-browsers

0
source share

The fastest way to get a DOM element is to use pure JavaScript and call it by id.

 var element = document.getElementById('element); 
0
source share

All Articles