Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantages to DOMParser vs template & innerHTML

I'm looking for the best way to handle parsing HTML or XHTML (XML serialized) markup and inserting it into the DOM of a webpage which could either be text/html or application/xhtml+xml. Not looking to use libraries like jQuery and really only care about compatibility with the latest version of Chrome.

I see two possible solutions.

  • Template & innerHTML:

    let temp = document.createElement('template');
    temp.innerHTML = markuptext;
    document.body.appendChild(temp.content);
    
  • DOMParser:

    let parser = new DOMParser();
    let doc = parser.parseFromString('<div xmlns="http://www.w3.org/1999/xhtml">' + markuptext + '</div>', 'application/xhtml+xml');
    let frag = document.createDocumentFragment(), childNode;
    while (childNode = doc.documentElement.firstChild) {
        frag.appendChild(childNode);
    }
    document.body.appendChild(frag);
    

I was hoping someone could point out the advantages/disadvantages of these two approaches.

With Template & innerHTML I am assuming Chrome will choose to parse as HTML/XML depending on the content type of the page and there is probably no way to change that. It seems Template & innerHTML allows fragments like <tr><td></td></tr> outside of a <tbody> regardless of if it is parsing as HTML or XML. DOMParser allows this too but only if it is parsing as XML.

like image 471
Chris_F Avatar asked May 16 '16 07:05

Chris_F


People also ask

What is the use of DOMParser?

The DOMParser interface provides the ability to parse XML or HTML source code from a string into a DOM Document . You can perform the opposite operation—converting a DOM tree into XML or HTML source—using the XMLSerializer interface.

Is DOMParser safe?

DOMParser created documents are created with scripting disabled; the script is parsed, but not run, so it should be safe against XSS.


2 Answers

It depends what is your goal. If you want just append parsed html/xhtml 'as is' then go with .innerHTML, its easier and usually faster. Hovewer, from my experience, often, you have to do some kind of transformations, then using dom operations is best way. But you should avoid appending node by node to document.body in loop, because it is slow and inefficient, just create some 'dummy' dom element, add nodes to it in loop, than append whole object:

let div = document.createElement('div');
let childNode;
while (childNode = doc.documentElement.firstChild) {
    div.appendChild(childNode);
}
document.body.appendChild(div);

One important note, about trying to find most efficient solutions in JS. JS performance highly depend on javascript engine, and what parts of js will be optimized in the future. So you should always write some kind of performance tests ( or use prepared test suites), especially about slow 'parts' like DOM API. Good news is that engine developers tend to favor well known solutions and 'good practices' to be optimized and they usually leave 'bad parts'.

Here are some good tests on innerHTML vs DOM append: http://andrew.hedges.name/experiments/innerhtml/

Appending to DOm without creating 'dummy' div: https://coderwall.com/p/o9ws2g/why-you-should-always-append-dom-elements-using-documentfragments

And more technical explanations about .innerHTML, .appendChild, .insertAdjacentHTML" "innerHTML += ..." vs "appendChild(txtNode)"

like image 176
Jazzman Avatar answered Sep 20 '22 16:09

Jazzman


Maybe a mixed approach?

var dom = new DOMParser().parseFromString('<template>'+ markuptext +'</template>','text/html').head;
document.getElementById('my-div').appendChild(dom.firstElementChild.content);
like image 22
swannty Avatar answered Sep 17 '22 16:09

swannty