Which is better - Ext.get() or document.getElementById() - javascript

What is the difference between Ext.get() and document.getElementById() in terms of performance? Will Ext.get() be slower as it may internally call document.getElementById() ? Or is there any specific advantage of using Ext.get() ?

The principle advantage of Ext.get over getElementById is that it returns to you an Ext.Element instance. This instance not only contains the DOM node reference that getElementById would give you but also significantly extends it - offering a suite of convenience methods, event normalization, and an ironing out of cross-browser differences.
On the surface getElementById may have some minuscule speed gain over Ext.get simply on the basis of one less function before getting to the same fundamental DOM call. However, in terms of overall performance what you do with the element after retrieval will likely have much more impact than the retrieval itself. Having the Ext.Element wrapper on hand may prove to be quite beneficial.
You may want to have a look at Ext.fly as well. This method is similar to Ext.get with exception that it returns to you a singleton Ext.Element instance. It won't be any good if you need to store the element for later use, but if you are doing simple, one-off operations against unique DOM nodes it may be cheaper than Ext.get.

document.getElementById() is native JavaScript and so will be faster than Ext.get()
Now why Ext.get() is there at all,
document.getElementById() returns a DOM element, while Ext.get() returns an Ext object which is apt for chaining purposes.
And this is also the reason why jQuery have a $("#elm_id"). Please note that Ext.get() is also much easier to type :)

Ext.get() allows for using a String ID, an existing HTMLElement, or a Ext.Element - so it's a little bit more flexible. document.getElementById() only accepts the String ID.
That said, I'd just use document.getElementById() if it meets your needs. It's native to the browser and should be a little faster - and it's one less call that you're chaining yourself to a specific JavaScript framework with.

In terms of performance, native JS functions will always be faster.
However, I am not saying not to use JS Libraries, they are great as they:
reduce the time when writing your code
it make your code more readable
you write less code (reducing file-size and download time)
And in the end, maybe you even save time because less code means faster download and in some cases it could even beat the performance.
So yeah, it is the same to use one over the other, since in one hand you save time by performance ("document.getElementById()") and in the other you reduce file size and download time ("Ext.get()").
You can use both and there shouldn't be any noticeable difference.

As others have eluded to here the method used depends upon need, if you just want to get a reference to the dom element for some non Ext purpose you may as well use the native function, but if you intend to perform actions on the returned object in an Ext context, then Ext.get will return you an Element reference which offers additional methods.
Ext.get is shorthand for Ext.ComponentManager.get and whilst it is a call to a library function and may be less efficient is should be noted that there are ~180 methods available on Ext.Element, so if you need these it may be worth including wrapper call.
As owlness has mentioned, Ext.fly() is designed when you need to perform a single function on an element, eg. Ext.fly("myDiv").hide(); whereas Ext.get() is intended when you need a get a reference to an element for later use, eg. var something = Ext.get("myDiv"); then perhaps something.sort(); something.badger(); return something;

I'm unfamiliar with the Ext library, but with vanilla Javascript, there's only a handful of ways to get a particular element; you can get it by its ID, search for it after getting all elements by a tag name (this is how JQuery gets elements by class name I believe), or, new to HTML5, get an element by a class name. There's a few other ways if you get creative ;)
Just getting it by ID is the quickest, assuming you didn't save a local reference.
So, if all you're trying to do is get an element without doing whatever Ext.js does via that function call, vanilla Javascript will be much faster.

Related

Is it better to use a reference to a dom element inside a callback instead of retrieving it?

I'm not sure how to phrase this question concisely, so if it's been asked before (and I'm sure it has been) that's why I can't find the answer(s).
If I have something like the following code in Javascript/jQuery:
$('#my-clicky-thing').click(function() {
if ( document.getElementById('my-checkbox').checked ){
// whatever
}
}
...would it be more sensible / efficient to do this instead:
var myCheckbox = document.getElementById('my-checkbox');
$('#my-clicky-thing').click(function() {
if ( myCheckbox.checked ){
// whatever
}
}
The latter approach seems to me like it would be more efficient. I'm assuming that a reference to the checkbox is bound to the click callback function when it is created, so using the checkbox reference would be faster than having to call getElementById to fetch it.
I'm just using this as a simple example. I don't have any formal Javascript training, but in practice, I usually always go with the reference approach. I just never stopped to think if there are any drawbacks or gotchas with doing this.
The latter approach seems to me like it would be more efficient.
That depends on what you mean by "efficient." It's less memory-efficient, for instance. But unless you have millions of them, the memory impact is unlikely to matter.
I'm assuming that a reference to the checkbox is bound to the click callback function when it is created...
Yes, it is, because the callback is a closure over the context in which that variable exists.
... so using the checkbox reference would be faster than having to call getElementById to fetch it.
Infinitesimally, yes. getElementById is very fast, because the browser keeps an index of elements by their ID and so it's a very, very, very quick lookup.
A more complex DOM query would be slower, but clicks are nothing like time-sensitive, so it's extremely unlikely to matter. A slow query in relation to an event that happens a lot (like mousemove) would argue for caching the reference; otherwise, it really doesn't matter and the decision of whether to keep the reference vs. looking it up is probably best driven by other factors, such as whether the element may go away, whether the closure will otherwise be optimized away (e.g., nothing else in it), that sort of thing.
You are definitely correct. Looking for the element in the DOM on every click is less efficient using jQuery's $() (see note). Keeping a reference to it is always a good practice.
It is especially recommended if you are planning to look for it more than once and perform several actions on it.
The only drawback I can think of is that when done excessively you'll end up having lots of variables sitting around holding references.. So this one is up to you to consider in your implementation.
For example, if you have a lot of these elements that need to be referenced, hold a reference to their container instead of to each one of them. Finding them within their container is likely to be more efficient than searching the entire DOM.
Note: As #T.J.Crowder mentioned, getElementByID is fairly fast and you shouldn't worry about it in this case. My answer is general and especially referring the $() selector for jQuery.
It's kind of general rule imo : keep reference to object as long as you may require access to this object though it's different for Java/C# where garbage collector removes all objects that does not have references so if you keep reference to object - you keep object in memory even when you don't need it.
But in your case i believe it doesn't really matter as click is event that fires too rare to make big difference. It would make more sense if you would like to access 50 different dom elements like 10 000 times each.

Why cache jQuery objects?

So why are we supposed to cache jQuery objects?
In the following scenario:
var foo = $('#bar');
foo.attr('style','cool');
foo.attr('width','123');
$('#bar').attr('style','cool');
$('#bar').attr('width','123');
Why is the first option so much better than the second option?
If it's because of performance, how does it reduce usage?
Because the jQuery function has a lot of code in it, which involves unnecessary overhead if you execute it more than once with the same inputs expecting the same outputs. By caching the result, you store a reference to the exact element or set of elements you're looking for so you don't have to search the entire DOM again (even if it's a fairly fast search). In many cases (simple pages with small amounts of code) you won't notice a difference, but in the cases where you do it can become a big difference.
You can see this in action by testing your example in jsPerf.
You can also think of it as an example of the Introduce Explaining Variable refactoring pattern for readability purposes, particularly with more complex examples than the one in the question.
The jQuery selector $('#foo') searches the entire DOM for the matching element(s) and then returns the result(s).
Caching these results means that jQuery doesn't have to search the DOM every time the selector is used.
EDIT: document.getElementById() is what jQuery uses to search the DOM, but there's never enough jQuery.

Why check for element/attributes before removing it?

In the Working with the Attribute Node chapter in Learning Javascript - A Hands-On Guide to the Fundamentals of Modern Javascript, the author Tim Wright said on Page 73:
Removing an attribute is as simple as getting one. We just target the element node and use the method removeAttribute() to get it out of there. There are no Javascript exceptions thrown if you try to remove an attribute that doesn't exist, but it's still best practive to use the same hasAttribute() method we mentioned earlier, shown in Listing 4.6.4
Listing 4.6.4 Javascript Used to Remove the Class Value of Our Image
if(document.getElementById("pic").hasAttribute("class")) {
document.getElementById("pic").removeAttribute("class");
}
If there's no exceptions thrown either way, isn't checking whether it exists or not redundant? The same outcome will arise. The argument that the book says is that check for the paramenter before removing it saves the browser parsing through unneccesary code, but if(document.getElementById("pic").hasAttribute("class")) {} is even longer than document.getElementById("pic").removeAttribute("class"); on its own!
Why is this best practice then?
In my opinion your assumption is absolutely right. I think the "advice" in the book is kind of catastrophic (to use a dramatic term). Havent heard about that "best practice" anywhere before. There is absolutely nothing you could achieve by using element.hasAttribute prior to removing / changing an attribute but slow down your code. A browser does not magically have a lookup list for attributes to check for their existence that is not used when it set or get an attribute. It may be best practice - in the authors opinion - for producing readable and understandable code, though.
Furthermore, in my opinion you should never use setAttribute at all! Use setAttribute only then there is no built in standard method for getting or setting a certain attribute. Here class is in question, use
element.className = 'myclass';
instead of
element.setAttribute('class', 'myclass');
Browsers have optimized routines when using such standardized methods. If not being used when you assign or delete an attribute to an element then the browser has to figure out what kind of attribute it is, and may perhaps trigger special operations afterwards - not everytime nessecary.
You can check if a browser supports a specific attribute-method like this
if (typeof window.document.body.className === 'string') {
//className is supported for node elements
}
Most of those attribute-methods acts like getters and setters. You can read and write, and the use of some them are even more effective than other approaches. Example :
element.outerHTML = '';
clean more memory up than
element = null;
It is of course not an attribute to an element, but to show why one should prefer using built in methods targeting a specific part of an element.
There is many, many standard methods as element.className you can use to target a specific standard attribute. They are mostly named as the attribute name in camelcase notation. Use setAttribute only for your own custum attributes, like
element.setAttribute('data-my-custum-attribute', 'hello');
Which is perfectly legal markup according to the HTML5 standard. Or use it as a fallback, if the browser doenst support a certain attribute method. This can be the case for very old browsers. But even IE6 supports className.
I will recommend two books which I think is really valuable for understanding javascript in the depth (not claiming that I do in full, but those books have helped me a lot) :
Javascript - the good parts, by Douglas Crockford
Secrets of the JavaScript Ninja, by John Resig (the guy behind jQuery)
Buy the books! They are gold as reference on your desk.
One thing I have on my mind is that removeAttribute might be a much heavier function call regarding the operations it does, i.e., it modifies the DOM and HTML, and could also affects meta data in the browser.
In comparison, hasAttribute is just a read operation, which is much lighter and won't have impact on meta data. So it's better to check if the element has the attribute or not.
If removeAttribute itself already does hasAttribute checking, then I agree it is pretty much redundant.
its useful for when you are writing a large program or working in a group.... you need to check that you dont remove something that is being used by something/someone else. if there is a more technical answer, hopefully someone else will supply it.

How to "correctly" create an object which inherits from Element?

I am writing an HTML5 application that involves a lot of XML manipulation, part of this manipulation involves comparing the versions of two different XML Elements.
What I need is for every Element, Attr, and TextNode (all of which inherit from Node, AFAIK) object that gets created to have associated version information, but still be able to behave like a normal Element, Attr, or TextNode. The current working solution I am using to store the version information, is the following:
Node.prototype.MyAppAnnotation = {
Version : null
};
Now, I understand that augmenting built-in types is considered bad form, but beyond this technique, I'm at a loss for how to get the desired functionality. I don't think I can encapsulate the Node in a wrapper because I need the Node related properties and functions exposed on the wrapper. I might be able to write some sort of pass-through functions for the wrapper, but that seems really clunky.
I feel that because the app I'm writing is an HTML5 app, and as such only has to run on the most modern browsers (all of which support the augmentation of built-ins), makes this technique appropriate. Also, by providing a sufficiently obscure name to my augmentation object, I can avoid all naming collisions (except for intentional collisions). I've also explored inheritance-based solution using Google's Closure library. However, it appears that because Element, Node and TextNode don't have direct constructors (i.e. they're created off of a Document object), this technique will not work either.
I was wondering if someone could either a) recommend an elegant way of achieving this effect without augmenting Element, or b) provide a compelling reason for why I shouldn't break the "don't augment built-ins" rule in this case.
Many Thanks,
Jarabek
Your idea is theoretically valid, but there's a weird feeling I get when reading about it.
First of all - you don't have to augment any prototypes. If you just do somedomnode.myweirdname='foo' it will become a field of that object. That's what javascript does ;)
So when there is no version you'll get undefined instead of null.
But, if you want to add more functionality or wrap dom node in anything - there's a bit of history of doing that. Most of that history is dominated by stuff like jQuery :)
Just create an object that has a field containing the node. And then you can access it really simply:
myobject.node
And create the object with some constructor or just factory function:
var myobject = createDomNodeWrapper(domnode)

JQuery selector - full or optimized scan?

Code example:
$JK("body *").each(function() { ... });
Will JQuery fill the elements' array first before calling each() or there is kinda LINQ-style optimization, so that function will be called during the DOM tree traversal? I guess that this optimization might (or not) be deployed into the JS engine. If so, how one can know if it is implemented for this or that engine/browser?
It builds the entire list first. I can't imagine how it could be done in the browser/JavaScript engine, though I guess it might be possible to make NodeList be lazy somehow.
The jQuery object looks like an Array instance (it isn't, but it tries to look like one), meaning that you can randomly-access elements by numeric index. It'd be quite a trick to make that be lazy.
Note that modern browsers support DOM-accessing functions that push a lot of the work down into the browser's internals, so that often — as, I suspect, in the case of your selector, which is really just
document.getElementsByTagName('body')[0].getElementsByTagName('*')
the browser hands back the complete list to jQuery. That's why I mentioned making the NodeList object be lazy, but I still think it'd be pretty hard given the semantics of JavaScript.
It fills the elements array first.
Since this is really just javascript and javascript is single threaded (except for web workers which are not being used here and can't access the DOM anyway), it happens like this:
This function call is executed to completion:
$JK("body *")
That function returns a jQuery object upon with the
.each()
method is called. In that method, it iterates through the array of DOM elements and calls the callback function once for each DOM element.

Categories

Resources