tags:

views:

260

answers:

4

I was just reading this: http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx

And had some questions about some of the advocated tricks:

9 - Give your selectors a context:

What's the difference between using a context and using a more specific selector?

Rather than doing

var selectedItem = $('#listItem' + i, $('.myList'));

What about

var selectedItem = $('.myList>#listItem' + i);

Which one is faster/better, or is there no difference?

12 - Learn about event delegation:

I would imagine that at low handler counts event delegation is slower than normal binding.

How many handlers is the time when you should start using event delegation?

Also, what is the difference (in terms of how fast or how 'good' it is) between using delegation and creating a click target in dom, having the user click that click target, and then have the click target find the elements to manipulate. Is this method faster or is delegation faster?

Edit: In addition, how many levels should you be delegating? Is it better to delegate something 10 levels away, or to simply bind 2 handlers.

13 - Use classes to store state

14 - Even better, use jQuery's internal data() method to store state:

Why use data vs classes? Is data faster? I think I generally find classes to be easier to read, contradicting what it says in the blog entry, because I can see it in the DOM.

Thanks!

+2  A: 

I cannot answer you all questions, but probably could provide some relevant information, which can be useful.

9 - Give your selectors a context:

First one is more sophisticated, since that way you can pass an iframe element and lookup there. I don't think there is a difference in the performance.

From documentation:

JQuery( expression, context)
The core functionality of jQuery centers around this function. Everything in jQuery is based upon this, or uses this in some way. The most basic use of this function is to pass in an expression (usually consisting of CSS), which then finds all matching elements.

By default, if no context is specified, $() looks for DOM elements within the context of the current HTML document. If you do specify a context, such as a DOM element or jQuery object, the expression will be matched against the contents of that context.

14 - Even better, use jQuery's internal data() method to store state:

This function can be useful for attaching data to elements without having to create a new expando. It also isn't limited to a string. The value can be any format. Class is more general, here you able to bind your data with element or set of elements. It can be used as metadata in some perspective.

PS. You can find more information here

Artem Barger
On data vs classes, still, in a situation where you can use both, which one is preferred?
Jourkey
to store state which related to some content I would prefer data, when we talking about state with further functional implication(see invokation) I would like to use objects.
Artem Barger
+1  A: 

For (9)

Since there should only ever be one element with a given id the extra stuff doesn't seem necsesary... unless you are testing to see if it is actually there (in that exact nesting)

If the reverse is the case (e.g. the context is very specific, and the selected element(s) you want are fairly generic) I can see how this would help...

//LI elems with CSS class "foo"
//but only inside the element with the ID "onlyInHere"
$('li.foo', '#onlyInHere')
scunliffe
+4  A: 

9 - Give your selectors a context:

var selectedItem = $('#listItem' + i, $('.myList'));

v/s

var selectedItem = $('#listItem' + i);

According to the article the first one should be faster. But I can't see how this can be...

First of all accessing by ID is one of the fastest ways to get to an element. It's just a lookup from global ID-s hash table. Adding a context to it should add no speed. Looking up the context should take some extra time and therefore the first example should be slower.

I also did some measurements and found that indeed the first one is many times slower.

As for this:

var selectedItem = $('.myList>#listItem' + i);

That should be about the same speed as the first one. And according to my measurements it is indeed about the same, just a little faster.

But the specifying context can be beneficial when dealing with other types of selectors and especially you reuse it, like that:

var ctx = selectedItem = $('.myList')
for (var i=0; i<1000; i++) {
    var selectedItem = $('.listItem' + i, ctx);
}

In this example it gives you a considerable speed boost.

Like with everything else related to performance - you have to measure before you know if something applies in your specific situation.

How many handlers is the time when you should start using event delegation?

When I feel that the page is slow. 99% of the time normal event handlers are good enough.

Rene Saarsoo
+1 agreed. The concept is correct, but the sample is a bad choice.
scunliffe
specifying a context is the same as $( context ).find( selector );
Russ Cam
+1  A: 

Regarding #9:

When you provide a context to your selector queries you limit the size of the tree being traversed to find the elements matching your selector, especially if you're using selectors that use tag names like: $('div > span').

Performance depends on the type of selector and the number of elements in the context you're providing.

Take a look at getElementsByTagName to better understand these issues.

As for "which one is better" - this depends heavily on the size of the DOM being traversed and on a number of other elements, but in general, the first selector (the one with the context) should be faster.

Regarding #12:

In general, it is good practice to use event delegation when the number of child elements inside a parent element (cells inside a table, for example) is unknown and is expected to be quite large. This usually applies to cases where data is pulled from a server. The common scenarios are tree and grid structures.

Regarding #13:

I think the example provided in the document you're referring to does the job, but I'll try to elaborate a bit further. Classes are a common and standard way to attach additional information to HTML nodes. Lets take a Tab bar as an example: assuming you have a standard class "tab" which applies to every tab in your tab bar, you could add an additional class to one of the tabs to indicate that it is currently selected. Adding an additional class called "selected" would allow you to apply a different style to the selected tab and query the tab bar using jQuery for some additional logic (for example: check which tab is currently selected to perform an HTTP request and retrieve the content for this tab).

Regarding #14:

Classes are limited in the type and amount of data you can (or should) store in them. Data is a more flexible way to store large amounts of state data for HTML elements.

Lior Cohen