最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - When do you use DOM-based Generation vs. using stringsinnerHTMLJQuery to generate DOM content? - Stack Overflow

programmeradmin1浏览0评论

I was wondering when to use DOM-based generation versus .innerHTML or appending strings using JQuery's .append method? I read a related post here Should you add HTML to the DOM using innerHTML or by creating new elements one by one? but I'm still unsure of the use case for each method.Is it just a matter of performance where I would always choose one over the other?

Let's say that form is an arbitrary variable:

DOM generation

            var div = document.createElement("div"),
            label = document.createElement("label"),
            input = document.createElement("input");

            div.appendChild(label);
            div.appendChild(input);

            form.appendChild(div);

JQuery

           $(form).append("<div><label></label><input></input></div>")

I was wondering when to use DOM-based generation versus .innerHTML or appending strings using JQuery's .append method? I read a related post here Should you add HTML to the DOM using innerHTML or by creating new elements one by one? but I'm still unsure of the use case for each method.Is it just a matter of performance where I would always choose one over the other?

Let's say that form is an arbitrary variable:

DOM generation

            var div = document.createElement("div"),
            label = document.createElement("label"),
            input = document.createElement("input");

            div.appendChild(label);
            div.appendChild(input);

            form.appendChild(div);

JQuery

           $(form).append("<div><label></label><input></input></div>")
Share Improve this question edited May 23, 2017 at 12:04 CommunityBot 11 silver badge asked Jul 18, 2012 at 21:14 AnthonySAnthonyS 2,4692 gold badges24 silver badges17 bronze badges 3
  • Look at both code samples and seeing as the second is not only, shorter, more readable and faster, I can't see any reason to go with direct DOM manipulation. – Oded Commented Jul 18, 2012 at 21:17
  • A closing </input> tag? Is that valid? – David Thomas Commented Jul 18, 2012 at 22:24
  • @DavidThomas Correct, the (HTML) <input> doesn't have a closing tag (but XML has, as seen here: w3schools./tags/tag_input.asp#midcontentadcontainer ). That can be another reason to use the createElement() functions, they always give you correct tags. – Sebastian Norr Commented Jul 26, 2019 at 6:24
Add a ment  | 

3 Answers 3

Reset to default 5

The second one is more readable, although that es from jQuery which does the innerHTML work for you. In vanilla JS, it would be like this:

form.insertAdjacentHTML("beforeend", "<div><label></label><input></input></div>");

...which I think beats even jQuery. Although, you should not worry about performance. The performance always depends on the amount of nodes to insert - for single ones, the HTML parser would be slower than creating them directly, for large HTML strings the native parser is faster than the script. If you really do worry about performance, you will need to test, test, test (and I'd say there is something wrong with your app).

Yet, there is a great difference between the two methods: With #1, you have three variables with references to the DOM elements. If you would for example like to add an event listener to the input, you can immediately do it and don't need to call a querySelector on form, which would be much slower. Of course, when inserting really many elements - with innerHTML -, you wouldn't need to do that at all because you would use delegated events for a real performance boost then.

Note that you can also shorten method #1 with jQuery to a oneliner:

var div, label, input;
$(form).append(div=$("<div/>").append(input=$("<input/>"),label=$("<label/>")));

My conclusion:

  • For creating only few elements the DOM approach is cleaner.
  • Mostly, html strings are more readable.
  • None of the two is faster in standard situations - benchmark results vary wide.

Personally, I don't like (direct) innerHTML for a few reasons, which are outlined well in these two answers and here as well. Also, IE has a bug on tables (see Can't set innerHTML on tbody in IE)

Generally speaking, hitting the DOM repeatedly is much slower than say swapping out a big block of HTML with innerHTML. I believe there are two reasons for this. One is reflow. The browser has to recalc for potential layout impact across potentially wide variety of elements. The other, I believe, and somebody correct me if I'm wrong, is that there's a bit of overhead involved in translating the stuff going on at the browser's post-piled execution environment where rendering and layout state is being handled into an object you can use in JavaScript. Since the DOM is often under constantly changing conditions you have to run through the process every time with few opportunities to cache results of any kind, possibly to a degree even if you're just creating new elements without appending them (since you're likely to going to want pre-process CSS rules and things like what 'mode' the browser is in due to doctype, etc, that can be applied in a general context beforehand).

DOM methods allow you construct document fragments and create and append HTML element to those without affecting the actual document layout, which helps you avoid unnecessary reflow.

But here's where it gets weird.

  • Inserting new HTML into a node with nothing in it - close to a tie or something innerHTML is typically much faster at in a lot of (mostly older) browsers

  • Replacing a ton of HTML contents - this is actually something where DOM methods tend to win out when performance isn't too close to call.

Basically, innerHTML, if it stinks, tends to stink at the teardown process where large swaps are happening. DOM methods are better at teardown but tend to be slower at creating new HTML and injecting directly without replacing anything when there's any significant difference at all.

There are actually hybrid methods out there that can do pretty marvelous things for performance when you have the need. I used one over a year ago and was pretty impressed by response time improvement for swapping large swathes of HTML content for a lazy-loading grid vs. just using innerHTML alone. I wish I could find a link to the guy who deserves credit for figuring this out and spelling it out on the web (author, has written a lot of RegEx stuff too - couldn't google for the life of me).

As a matter of style vs perf, I think you should avoid tweaking the actual DOM node structure repeatedly but constructing HTML in a document fragment beforehand vs. using innerHTML is pretty much a matter of judgement. I personally like innerHTML for the most part because JS has a lot of powerful string methods that can rapidly convert data to HTML-ready strings. For instance:

var htmlStr = '<ul><li>' + arrayOfNames.join('</li><li>') + '</li></ul>';

That one-liner is a UL I can assign directly to innerHTML. It's almost as easy to build plete tables with the right data structure and a simple while loop. Now go build the same UL with as many LIs as the length of the arrayOfNames with the DOM API. I really can't think of a lot of good reasons to do that to yourself. innerHTML became de facto standard for a reason before it was finally adopted into the HTML 5 spec. It might not fit the node-based htmlElement object tweaking approach of the DOM API but it's powerful and helps you keep code concise and legible. What I would not likely do, however, is use innerHTML to edit and replace existing content. It's much safer to work from data, build, and swap in new HTML than it is to refer to old HTML and then start parsing innerHTML strings for attributes, etc when you have DOM manipulation methods convenient and ready for that.

Your chief performance concern should probably be to avoid hammering away at the 'live' portions of the DOM, but the rest I would leave up to people as a matter of style and testing where HTML generation is concerned. innerHTML is and has for years now been in the HTML5 working draft, however, and it is pretty consistent across modern browsers. It's also been de facto spec for years before that and was perfectly viable as an option since before Chrome was new, IMO but that's a debate that's mostly done at this point.

It is just a matter of performance. Choose the one that fits you best.

jsPerf is full of those performance test, like this one: test

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论