Store into variable an element id vs element object reference - javascript

I'm writing a library where I need to store some data to be able to address quickly DOM elements. I don't know if I should store element ids (strings) and do $(document.getElementById(this.idVar)).jqueryMagic() or store the element object reference (object HTML*Element) and do $(this.eleVar).moreJqueryMagic(). I don't mind readability, I just want to know the difference in memory space between each method and the difference in performance.
Thanks in advance!

If performance on this level is an issue you should not use jQuery, it is a way bigger performance hog than a detail like this. (That is not to say that jQuery is bad. You do in general pay for it in performance, but that is most often not an issue.)
If you are accessing the object multiple times general wisdom is that storing the object reference is faster as you eliminate a level of dereferencing.
If you use jQuery you should in general store the jQuery wrapper rather than the raw element, as to avoid creating redundant wrappers:
this.jqVar = $(document.getElementById(this.idVar))
this.jqVar.jqueryMagic()

Related

Is there a direct way (at the lower level) to do $('#id')?

I mostly call jQuery elements by the id of the DOM object using the $('#id') syntax. I think that this goes through the selector algorithm, and spends some time on that process.
I was wondering if there is a way to dig into that function and access jQuery objects from the id of the DOM in a more direct way (at the lower level) to improve performance. Will it worth doing so? If so, how can I do it?
If you want to improve performance, keep a jQuery object that's used for single node synchronous operations
var _id = $(document);
Then update its 0 property when you need to fetch by ID.
_id[0] = document.getElementById("id");
_id.css(...);
This eliminates the vast majority of its overhead. Because JS is single threaded, you can reuse this object wherever needed. But if you want to do some operation in a setTimeout(), you should probably just create a new object to be safe.
When you pass jQuery a single, lone ID selector, it automatically skips any selector processing and calls document.getElementById() directly. It's only when the selector string consists of anything more than an ID selector that it always treats it like a selector (this includes selectors like div#id, .class#id, or even #wrapper #id).
In most cases, this is something you don't have to worry about, since jQuery already does a lot of optimization for you. But if you're paranoid and want to remove every hair and every ounce of any possible overhead, see cookie monster's answer.
Going native will always be faster / more direct:
var id = document.getElementById("id");
But you will loose the benefits of wrapping your object in a jQuery wrapper.
You can also do :
$(document.getElementById("id"))
That way you are passing in the direct object rather than performing a lookup on the dom.
You want to use getElementById like this
var name = document.getElementById('id');
Actually.... this will depend on the browser u will be using to run the script.... here i did some dig on the internet..... i found a test result on this topic.....
Here is the Site
As to them JQuery selectors are faster than the native JS code.

Better practice for HTML5 web app: using getElementByID or storing a reference?

I'm building one of my first web apps using HTML5, specifically targeting iPhones.
Since I'm pretty new to this, I'm trying to develop some good coding habits, follow best practices, optimize performance, and minimize the load on the resource-constrained iPhone.
One of the things I need to do frequently... I have numerous divs (each of which has a unique id) that I'm frequently updating (e.g., with innerHTML), or modifying (e.g., style attributes with webkit transitions and transforms).
In general - am I better off using getElementByID each time I need a handle to a div, or should I store references to each div I access in "global" variables at the start?
(I use "global" in quotes because I've really just got one truly global variable - it's an object that stores all my "global" variables as properties).
I assume using getElementByID each time must have some overhead, since the function needs to traverse the DOM to find the div. But, I'm not sure how taxing or efficient this function is.
Using global variables to store handles to each element must consume some memory, but I don't know if these references require just a trivial amount of RAM, or more than that.
So - which is better? Or, do both options consume such a trivial amount of resources that I should just worry about which produces more readable, maintainable code?
Many thanks in advance!
"In general - am I better off using getElementByID each time I need a handle to a div, or should I store references to each div"
When you're calling getElementById, you're asking it to perform a task. If you don't expect a different result when calling the same method with the same argument, then it would seem to make sense to cache the result.
"I assume using getElementByID each time must have some overhead, since the function needs to traverse the DOM to find the div. But, I'm not sure how taxing or efficient this function is."
In modern browsers especially, it's very fast, but not as fast as looking up a property on your global object.
"Using global variables to store handles to each element must consume some memory, but I don't know if these references require just a trivial amount of RAM, or more than that."
Trivial. It's just a pointer to an object that already exists. If you remove the element from the DOM with no intention to use it again, then of course you'll want to release your hold on it.
"So - which is better? Or, do both options consume such a trivial amount of resources that I should just worry about which produces more readable, maintainable code?"
Depends entirely on the situation. If you're only fetching it a couple times, then you may not find it worthwhile to add to your global object. The more you need to fetch the same element, the more sense it makes to cache it.
Here's a jsPerf test to compare. Of course size of your DOM as well as length of variable scope traversal and the number/depth of properties in your global object will play some role.
Using a local variable or even an object property is much faster than getElementById(). However, both are so fast that their performance is generally irrelevant compared to any other operation you might do once you have the element. Event setting a single property on the element is orders of magnitude slower than retrieving it by either method.
So the main reason to cache an element is to avoid the rather long-winded document.getElementById(... syntax, or to avoid having element ID strings scattered all over your code.

Selectors and performance

Is there any benefit to performance when I do the following in Mootools (or any framework, really)?:
var elem = $('#elemId');
elem.addClass('someClass');
elem.set('some attribute', 'some value');
etc, etc. Basically, I'm updating certain elements a lot on the DOM and I was wondering if creating a variable in memory and using that when needed was better than:
$('#elemId').addClass('someClass');
$('#elemId').set('some attribute', 'some value');
The changes to $('#elemId') are all over the place, in various different functions.
Spencer ,
This is called caching and it is one of the best practices.
when you say
$('#elemId');
It will go and query the DOM everytime , so if you say
var elem = $('#elemId');
elem acts as a cache element and improves performance a lot.
This is manly useful in IE as it has memory leaks promblem and all
ready this document which is really good
http://net.tutsplus.com/tutorials/javascript-ajax/14-helpful-jquery-tricks-notes-and-best-practices/
It depends how you query the dom. Lookups by ID are extremely fast. Second most is css classes. So as long as you're doing it by only a single ID (not a complex selector containing an id), there shouldn't be much of a benefit. However, if you're using any other selector, caching is the way to go.
http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
https://developer.mozilla.org/en/Writing_Efficient_CSS
You first approach is faster then your second approach, because you "cache" the search on #elemId.
Meaning the calls to addClass and set don't require extra lookups in the DOM for your element.
However! You can link function calls:
$('#elemId').addClass('someClass').set('some attribute', 'some value');
Depending on your application caching or linking might work better, but definitely not identical sequential lookups in the same block.
Depending on the situation, caching can be as much as 99% faster then using a jQuery object every time. In the case you presented it will not make much difference. if you plan to use the selector many times, you should definitely cache the object as a variable so it doesn't get created everytime you run it.
A similar questions was answered at Does using $this instead of $(this) provide a performance enhancement?.
Check performance log http://jsperf.com/jquery-this-vs-this
You are considering using a local variable to cache a value of a potentially slow lookup.
How slow is the call itself? If it's fast, caching won't make much a difference. If it's slow, then cache at the first call. Selectors vary significantly in their cost-- just think about how the code must fine the element. If it's an ID, then the browser provides fast access, whereas classes and nodes my require full DOM scans. Check out profiling of jQuery (Sizzle) selectors to get a sense of these.
Can you chain the calls? Consider "chaining" method calls where possible. This provides the efficiency without introducing another variable.
For your example, I'd write:
$('#elemId').addClass('someClass').set('some attribute', 'some value');
How does the code read? Usually if the same method is going to be called multiple times, it is clearer to DRY it up, and use a local variable. The reader then understands the intent better-- you don't force them to scan all the jQuery calls to verify that they are the same. BTW, a fairly standard convention is to name jQuery variables starting with a $-- which is legal in Javascript-- as in
var $elem = $('#elem');
$elem.addClass('someClass');
Hope this helps.

Why use jQuery data to store variables instead of plain JavaScript objects?

Is there any benefit in using the data method when I can just store variables in plain javascript objects? It seems to me that using the jQuery data method is performance downgrade if it means re-looking up the DOM element to retrieve the value of the key, if the DOM element has not been referenced prior?
Sorry if this is painfully obvious to javascript devs, but I hope to understand this fully.
It's simply a case of convenience and it depends on your implementation as to whether you would use the data functionality. You would normally use .data() when you wanted to store related values for a specific DOM element or, more likely, a "collection" of DOM elements. You would normally then retrieve those values as you iterate through the elements and make a decision or perform an action based on the value. Even if you are going to retrieve one value - if you cached the jQuery DOM element(s) it would be an inexpensive call to retrieve the attached value.
Because you cannot easily store data related to a certain DOM element using "plain javascript objects". If your data is not related to a certain DOM object you shouldn't use $.data of course!
I figured.
The DOM element can and should be referenced prior when using data, and that wouldn't result in a performance hit thus (and we still maintain the DOM_Element-key-value relationship).
So the initial look up for 'body' when storing the key-value is the only performance cost, and subsequent data retrievals don't have to find 'body' again:
b = $('body');
b.data('key', 'value');
alert(b.data('key'));

What's wrong with adding properties to DOM Element objects?

I've been looking for a straight answer for this (I can think of lots of possiblities, but I'd like to know the true reason):
jQuery provides a .data() method for associating data with DOM Element objects. What makes this necessary? Is there a problem adding properties (or methods) directly to DOM Element Objects? What is it?
Is there a problem adding properties (or methods) directly to DOM Element Objects?
Potentially.
There is no web standard that says you can add arbitrary properties to DOM nodes. They are ‘host objects’ with browser-specific implementations, not ‘native JavaScript objects’ which according to ECMA-262 you can do what you like with. Other host objects will not allow you to add arbitrary properties.
In reality since the earliest browsers did allow you to do it, it's a de facto standard that you can anyway... unless you deliberately tell IE to disallow it by setting document.expando= false. You probably wouldn't do that yourself, but if you're writing a script to be deployed elsewhere it might concern you.
There is a practical problem with arbitrary-properties in that you don't really know that the arbitrary name you have chosen doesn't have an existing meaning in some browser you haven't tested yet, or in a future version of a browser or standard that doesn't exist yet. Add a property element.sausage= true, and you can't be sure that no browser anywhere in space and time will use that as a signal to engage the exciting DOM Sausage Make The Browser Crash feature. So if you do add an arbitrary property, make sure to give it an unlikely name, for example element._mylibraryname_sausage= true. This also helps prevent namespace conflicts with other script components that might add arbitrary properties.
There is a further problem in IE in that properties you add are incorrectly treated as attributes. If you serialise the element with innerHTML you'll get an unexpected attribute in the output, eg. <p _mylibraryname_sausage="true">. Should you then assign that HTML string to another element, you'll get a property in the new element, potentially confusing your script.
(Note this only happens for properties whose values are simple types; Objects, Arrays and Functions do not show up in serialised HTML. I wish jQuery knew about this, because the way it works around it to implement the data method is absolutely terrible, results in bugs, and slows down many simple DOM operations.)
I think you can add all the properties you want, as long as you only have to use them yourself and the property is not a method or some object containing methods. What's wrong with that is that methods can create memory leaks in browsers. Especially when you use closures in such methods, the browser may not be able to complete garbage cleaning which causing scattered peaces of memory to stay occupied.
This link explains it nicely.
here you'll find a description of several common memory leak patterns
It has to do with the fact that DOM in IE is not managed by JScript, which makes it completely different environment to access. This leads to the memory leaks http://www.crockford.com/javascript/memory/leak.html. Another reason is that, when people use innerHTML to copy nodes, all those added properties are not transfered.

Categories