I asked this question, and it turned out that when removing an attribute from an element, checking whether the element exists first using elem.xxx!==undefined
makes the runtime faster. Proof.
Why is it quicker? There's more code to go through and you'll have to encounter the removeAttribute()
method whichever way you go about this.
Dot notation is faster to write and easier to read than bracket notation. However, you can use variables with bracket notation, but not with dot notation. This is especially useful for situations when you want to access a property but don't know the name of the property ahead of time.
Dot notation is one way to access a property of an object. To use dot notation, write the name of the object, followed by a dot (.), followed by the name of the property. Example: var cat = { name: 'Moo', age: 5, }; console.
Dot notation is faster to write and clearer to read.
We must use bracket notation whenever we are accessing an object's property using a variable or when the property's key is a number or includes a symbol or is two words with a space.
Well, first thing you need to know is that elem.xxx
is not the same as elem.getAttribute()
or any other method relative to the attribute.
elem.xxx
is a property of a DOM element while attribute and element on the HTML inside the DOM, both are similar but different. For exemple, take this DOM element: <a href="#">
and this code :
//Let say var a is the <a> tag
a.getAttribute('href');// == #
a.href;// == http://www.something.com/# (i.e the complet URL)
But let take a custom attribute : <a custom="test">
//Let say var a is the <a> tag
a.getAttribute('custom');// == test
a.custom;// == undefined
So you can't really compare the speed of both since they don't achieve the same result. But one is clearly faster since properties are a fast access data while attribute use the get/hasAttribute DOM functions.
Now, Why without the condition is faster? Simply because removeAttribute
doesn't care is the attribute is missing, it check if it is not.
So using hasAttribute
before removeAttribute
is like doing the check twice, but the condition is a little slower since it need to check if the condition is satisfied to run the code.
I have a suspicion that the reason for the speed boost are trace trees.
Trace trees were first introduced by Andreas Gal and Michael Franz of the University of California, Irvine, in their paper Incremental Dynamic Code Generation with Trace Trees.
In his blog post Tracing the Web Andreas Gal (the co-author of the paper) explains how tracing Just-in-Time compilers works.
To explain tracing JIT compilers as sententiously as possible (since my knowledge about the subject isn't profound) a tracing JIT compiler does the following:
true
branch of an if
statement is executed).Now let's take a look at your code and understand what is causing the speed boost:
if (elem.hasAttribute("xxx")) {
elem.removeAttribute("xxx");
}
This code has a code path (i.e. an if
statement). Remember that tracing JITs only optimize code paths and not entire functions. This is what I believe is happening:
hasAttribute
which is not JIT compiled because it's not a part of the conditional code path (the code between the curly braces).elem.removeAttribute("xxx");
In this test case we don't have any conditional code paths. Hence the JIT compiler never kicks in. Thus the code is slow.
if (elem.xxx !== undefined) {
elem.removeAttribute("xxx");
}
This is the same as the first test case with one significant difference:
elem.xxx
or undefined
is not changing every iteration this optimization makes the conditional check even faster.Of course this is just speculation on my part. I don't know the internals of a JavaScript engine and I hence my answer is not canonical. However I opine that it is a good educated guess.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With