Adding DOM Elements, what is the Right Way? - javascript

This question might be stupid, or basic.
Can someone explain which is the best method in adding DOM elements. We have these two ways of adding DOM elements.
Scenario: Need to add <strong>Hi</strong> inside an existing <div id="theEl"></div>.
By editing the HTML inside them.
document.getElementById("theEl").innerHTML = '<strong>Hi</strong>';
By using document.createElement().
var hi = document.createTextNode("Hi"),
strong = document.createElement("strong");
strong.appendChild(hi);
mydiv = document.getElementById("theEl");
document.body.insertBefore(strong, mydiv);
Questions
What is the best way to do? One is a single line, another is about five lines.
What is the performance aspect?
What is the right way or best practise?
Is there any difference between the codes as a whole?
If at all this question is not making sense, please let me know, I will be glad to close this or even remove this. Thanks.
For the close voter, this is not going to be a duplicate of that question. One thing I just noted is, using createElement() preserves the event handlers attached to the element. Even though that's a good point, any kind of basic web page, too has jQuery in them, which provides delegation and such stuff that allow me to have the event attached to the element even after change in HTML.

There is no "best" or "best practice". They are two different methods of adding content that have different characteristics. Which one you select depends upon your particular circumstance.
For creating lots and lots of elements, setting a block of HTML all at once has generally shown to be faster than creating and inserting lots of individual elements. Though if you really cared about this aspect of performance, you would need to test your particular circumstance in a tool like jsperf.
For creating elements with lots of fine control, setting classes from variables, setting content from variables, etc..., it is generally much easier to do this via createElement() where you have direct access to the properties of each element without having to construct a string.
If you really don't know the difference between the two methods and don't see any obvious reason to use one over the other in a particular circumstance, then use the one that's simpler and less code. That's what I do.
In answer to your specific questions:
There is no "best" way. Select the method that works best for your circumstance.
You will need to test the performance of your specific circumstance. Large amounts of HTML have been shown in some cases to be faster by setting one large string with .innerHTML rather than individually created an inserting all the objects.
There is no "right way" or "best practice. See answer #1.
There need be no difference in the end result created by the two methods if they are coded to create the same end result.

I actually like a combination of both: createElement for the outer element so you won't be removing any event handlers, and innerHTML for the content of that element, for convenience and performance. For example:
var strong = document.createElement('strong');
strong.innerHTML = 'Hi';
document.getElementById('theEl').appendChild(strong);
Of course, this technique is more useful when the content of the thing you're adding is more complex; then you can use innerHTML normally (with the exception of the outer element) but you're not removing any event listeners.

1. What is the best way to do? One is a single line, another is about five lines.
It depends on context. You probably want to use innerHTML sparingly as a rule of thumb.
2. What is the performance aspect?
DOM manipulation significantly outperforms innerHTML, but browsers seem to keep improving innerHTML performance.
3. What is the right way or best practise?
See #1.
4. Is there any difference between the codes as a whole?
Yes. The innerHTML example will replace the contents of the existing element, while the DOM example will put the new element next to the old one. You probably meant to write mydiv.appendChild(strong), but this is still different. The existing element's child nodes are appended to rather than replaced.

What did you mean by best? In just one DOM operation everything is good and shows the same performance. But when you need multiple DOM insertion, things go diferently.
Background
Every time you insert DOM node, the browser render new image of the page. So if you insert multiple child inside a DOM node, the browser renders it multiple times. That operation is the slowest that you will see.
The solution
So, we need to append most child at once. Use a empty dom node. The built in is createDocumentFragment();
var holder = createDocumentFragment();
// append everything in the holder
// append holder to the main dom tree
The real answer
If in the case is that you described, I would prefer the shortest solution. Because there is no performance penalty in one dom operation

Related

Setting (ARIA) role for HTML custom elements without explicit attribute?

I have a web app that displays and passes around user-editable semantic markup. For a variety of reasons, including security, the markup consists entirely of custom elements (plus the i, b, and u tags). For regular rendering, I simply have styles for all the tags and stick them straight in the DOM. This looks and works great.
Now I'm doing screen-reader testing, and things aren't great. I have a bunch of graphical symbols I want to add labels for. I've got divs that I want to make into landmarks. I've got custom input fields and buttons.
It would be easy enough to just add role= to all the different tag instances. But part of the reason for the custom markup is to eliminate all the redundant information from the strings that get passed around (note: they're also compressed). My <ns-math> tag should always have role="math", and adding 11 bytes to what might be tags around a single character is an actual problem when multiplied out over a whole article. I know this because the app started with a bunch of <span class="... type elements instead of custom.
For the fields and buttons, I've used a shadow DOM approach. This was necessary anyway to get focus/keyboard semantics correct without polluting the semantic markup with a bunch of redundant attributes, so it's easy to also slap the ARIA stuff on the shadow elements. Especially since the inputs are all leaf nodes. But most of my custom tags amount to fancy spans, and are mostly not leaf nodes, so I don't really want to shadow them all when they're working so well in the light DOM.
After a bunch of searching, it seems like the internals.role property from "4.13.7.4 Accessibility semantics" of the HTML standard is maybe what I want. I may well be using it incorrectly (I'm a novice at front-end), but I can't seem to get this to work in recent versions of Firefox or Chrome. I don't get an error, but it seems to have no effect on the accessibility tree. My elements are not form-associated, but my reading is that the ARIAMixin should be functional anyway. This is maybe a working draft? If this is supposed to work in current browsers, does anybody have a code snippet or example?
Is there some other straight-forward way to achieve my goal of accessibility-annotating my custom elements without adding a bunch of explicit attributes to the element instances?
So you want the benefit of adding a role or an aria-attribute without actually adding those attributes? The concept of an "accessibility object model" (AOM) has been bantering around a bit that would let you access and modify the accessibility tree directly but it's still in the works. Here's an article from a couple years ago that talks about it. Nothing official. Just one person's thoughts.
Further research shows that, as of this time, the abstracted accessibility options I'm asking for are not yet implemented.
For the time being: eliminating a number of page-owned enclosing divs from the accessibility hierarchy via role="presentation" significantly improved my overall tree. With those out of the way, the majority of my custom tags seem to be simply semantically ignored. This is mostly fine as the majority of my content is plain text.
Since I already mark up the vast majority of even single-character symbols, I've simply added all my symbols to the markup generator. Since everything is already in custom tags, I then use a shadow DOM span with role="img" and a character-specific aria-label to present the symbolic character.
My solution is still incomplete. I wish that I could convey the full richness of the semantic content I have available.

do I understand react virtual DOM sense correctly?

My way of thinking:
If we want to perform something on dom element we can do it by:
document.getElementById("#someId").DoSomething();
document.getElementById("#someId").DoSomethingElse();
In that situation browser needs to search entire DOM for #someId object. Then it forgets element and searches again to perform DoSomethingElse().
To solve "forgetting and searching again" problem we can save our element as JavaScript object.
var someElement = document.getElementById("#someId");
someElement .DoSomething();
someElement .DoSomethingElse();
Going further we can save entire group of elements or entire nodes to achieve better performance. One more step and we have whole DOM saved as an JavaScript object named virtual dom.
Is that correct way to understand purpose of virtual DOM?
Sorry for noob questions, I'm not front end developer, I'm just curious :)
The main point of the VirtualDOM is that, effectively, you're working on a copy of the real DOM. But the working with that copy is ways faster that working with the actual DOM, because it only has the thing that React actually needs, leaving specific browser issues aside.
The main problem with working with the actual DOM is that it's slow. At least, it's faster to work with that kind of copy, make your work there, and the changes have been done, then you update the actual DOM.
Yes, it sounds a bit crazy, but is faster to compute the differences between state changes and the change everything in "just one step", than making that changes with the actual DOM.
Additionally, you've used for your example just a single DOM node, but you're working on changes on DOM subtrees the thing is not that easy.
For an explanation with more detail you can take a look to this article: http://reactkungfu.com/2015/10/the-difference-between-virtual-dom-and-dom/

What kind of performance optimization is done when assigning a new value to the innerHTML attribute

I have a DOM element (let's call it #mywriting) which contains a bigger HTML subtree (a long sequence of paragraph elements). I have to update the content of #mywriting regularly (but only small things will change, the majority of the content remains unchanged).
I wonder what is the smartest way to do this. I see two options:
In my application code I find out which child elements of #mywriting has been changed and I only update the changed child elements.
I just update the innerHTML attribute of #mywriting with the new content.
Is it worth to develop the logic of approach one to find out the changed child nodes or will the browser perform this kind of optimization when I apply approach two?
No, the browser doesn't do such optimisation. When you reassign innerHTML, it will throw away the old contents, parse the HTML, and place the new elements in the DOM.
Doing a diff to only replace (or rather, update) the parts that need an update can be worth a lot, and is done with great success in rendering libraries that employ a so-called virtual DOM.
However, they're doing that diff on an element data structure, not an HTML string. Parsing that to find out which elements changed is going to be horribly inefficient. Don't use HTML strings. (If you're already sold on them, you might as well just use innerHTML).
Without concdering the overhead of calculating which child elements has to be updated option 1 seems to be much faster (at least in chrome), according to this simple benchmark:
https://jsbench.github.io/#6d174b84a69b037c059b6a234bb5bcd0

Removing an element - optimized way

What is the most efficient way in removing an element in DOM? (js or jquery)
removeChild()
This is what I was using always. But, recently came across this
The removed child node still exists in memory, but is no longer part
of the DOM. With the first syntax-form shown, you may reuse the
removed node later in your code, via the oldChild object reference.
So, If I don't want to preserve the removed element in memory (for better performance), what is the best method?
Or like in java, if reference is null, is it automatically garbage collected and no need to worry about performance? I am asking this specifically as I am dealing with svg and many append/remove calls are made.

Best method for creating element in JavaScript

What is the best approach to creating elements in JavaScript? I know about creating element using:
string example:
var div="<div></div>"
And another way is using
document.CreateElement('div').
Which one is the best method to achieve high performance? Is there is any other way to achieve this?
There is no single "best" approach, the best thing to do varies with the situation.
You basically have two choices:
Use the DOM methods to create elements (document.createElement('tagName')) and append/insert them into the DOM (appendChild, insertBefore), or
Use innerHTML on an existing element, assigning an HTML string to it; the browser will parse and render the HTML.
It used to be, just a couple of years ago, that innerHTML was a lot faster. But modern versions of browsers have improved the speed of DOM access dramatically, so really it comes down to what works best for the overall task you're performing.
When you append that div="<div></div>" to your body like I'm sure you meant to do, that works fine but is inefficient.
If you create the element, it creates its own object. The first option using the div var will allocate memory for the string and then again for the object itself and you have to reference it separately anyway. Basically doubling the browser's work.

Categories

Resources