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

javascript - What is better for DOM manipulation - the DOM API or innerHTML? - Stack Overflow

programmeradmin1浏览0评论

I have the following code:

tr = document.createElement("tr");
root.appendChild(tr);
td = document.createElement("td");
td.appendChild(document.createTextNode("some value"));
tr.appendChild(td);

Well, this code is same as

root.innerHTML = "<tr><td>some value</td></tr>";

The first version is probably a better way to go, because the browser does not have to render a string. But it is too long. Especially for bigger structures, this implementation is becoming really hard to read. So I felt like there is a better way to write this (without any JavaScript library). How would you implement this so the code would be more readable? (Right now I am separating code with comments.)

I have the following code:

tr = document.createElement("tr");
root.appendChild(tr);
td = document.createElement("td");
td.appendChild(document.createTextNode("some value"));
tr.appendChild(td);

Well, this code is same as

root.innerHTML = "<tr><td>some value</td></tr>";

The first version is probably a better way to go, because the browser does not have to render a string. But it is too long. Especially for bigger structures, this implementation is becoming really hard to read. So I felt like there is a better way to write this (without any JavaScript library). How would you implement this so the code would be more readable? (Right now I am separating code with comments.)

Share Improve this question edited Aug 29, 2010 at 11:41 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Aug 10, 2010 at 6:30 yilmazhuseyinyilmazhuseyin 6,6124 gold badges36 silver badges39 bronze badges 6
  • 3 Actually, innerHTML is much faster than creating DOM nodes. See quirksmode.org/dom/innerhtml.html. – kennytm Commented Aug 10, 2010 at 6:34
  • @KennyTM: Those test results are two years old. – Gumbo Commented Aug 10, 2010 at 6:42
  • 2 @Gumbo: innerHTML is still the fastest for Gecko (Firefox) and Presto (Opera) today, but for WebKit (Chrome & Safari) the “table method” is faster. Creating DOM nodes like what OP did is the slowest for all of these 4 browsers. – kennytm Commented Aug 10, 2010 at 6:57
  • @Gumbo: There is an annoyingly large number of browsers that haven't been upgraded in the past two years. – CurtainDog Commented Aug 10, 2010 at 6:59
  • @KennyTM: I guess it depends on the test environment. Because my tests have other results. If I average the averages of the browsers I tested (Chrome, Firefox, Opera, Safari) I get the following results: W3C DOM 1 27.5 ms, W3C DOM 2 28.25 ms, Table methods 27.75 ms, innerHTML 1 30 ms, innerHTML 2 30 ms. – Gumbo Commented Aug 10, 2010 at 7:26
 |  Show 1 more comment

9 Answers 9

Reset to default 6

You could always write wrapper functions around the clunky DOM API to make the code more readable. I usually use something like:

function newElement (type,attr,children) {
    var el = document.createElement(type);
    for (var n in attr) {
        if (n == 'style') {
            setStyle(el,attr[n]); /* implementation of this function
                                   * left as exercise for the reader
                                   */
        }
        else {
            el[n] = attr[n];
        }
    }
    if (children) {
        for (var i=0; i<children.length; i++) {
            el.appendChild(children[i]);
        }
    }
}
function newText (text) {
    document.createTextNode(text);
}

Then your can write much more declarative code:

var tr = newElement('tr',{},[
    newElement('td',{},[
        newText('some value')
    ])
]);

Just remember the differences between css and javascript:

var div = newElement('div',{
    className:'foo',
    style:{
        marginLeft:'10px'
    }
},[
    newText('notice we use "className" instead of class" '+
            'and "marginLeft" instead of "margin-left"')
]);

innerHTML is definitely faster than DOM (see discussion section). Some time ago, I came across a way to conveniently write large HTML structures with innerHTML, it's a little better that string concatenation, or having to write large structures:

var html = [
   '<ul class="myclass">',
      '<li class="item">item1</li>',
      '<li class="item">item2</li>',
      '<li class="item">item3</li>',
      '<li class="item">item4</li>',
      '<li class="item">item5</li>',
   '</ul>'
].join("");

root.innerHTML =html;

As I've mentioned in the comment, innerHTML is actually faster than creating DOM nodes, but it is unstructured.

A faster method than creating DOM nodes, but still structured, is to use the DOM 2 table methods:

var tr = root.insertRow(-1);
var td = tr.insertCell(0);
var txt = document.createTextNode("some value");
td.appendChild(txt);
// or simply: td.innerHTML = "some value";

Hey, I'm late to the game on this one, but wanted to add this information for you all. During some mobile browser development this issue came up for me, and wanted to see for myself which is better these days.

On my Android phone here's some interesting results:

      DOM: 614 / 25
innerHTML: 697 / 542
      DOM: 546 / 18
innerHTML: 639 / 552
      DOM: 604 / 12
innerHTML: 641 / 534
      DOM: 619 / 11
innerHTML: 643 / 554
      DOM: 618 / 13
innerHTML: 655 / 600

The first number is the actual execution of adding 2700 li elements. And, even more interesting is the second number, which is how long it takes the ol to flush out those results using innerHTML = '';

Try for yourself at DOM vs innerHTML.

innerHTML was originally an IE thing, I believe.

I also think you set it, as it is not a method, so that second example would be

root.innerHTML = "<tr><td>some value</td></tr>";

But to answer your question, innerHTML is more convenient, but it is often said to be slower. However, KennyTM says in the comments that it is much faster.

You have to decide if the performance trade off, which may probably be negligible, is worth doing it the DOM API way or the innerHTML way.

I would have reordered to make it more readable

var d = document;
td = d.createElement("td");
tr = d.createElement("tr");
td.appendChild( d.createTextNode("some value") );
tr.appendChild(td);
root.appendChild(tr);

Use jQuery http://jquery.com/

$('#root tbody').append('<td><td>some value</td></td>');

It will even use the proper DOM methods.

EDIT: From the jQuery docs:

jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.

** EDIT:** Also, I made the sample above a little more HTML conformant @koby ;)

Did you try to use a JavaScript templating engine?

They generally inject HTML strings by innerHTML and are way faster than DOM manipulations in both desktops and mobiles while keeping a separation between view and logic.

We use PURE which totally separates the HTML markup and the JavaScript logic. Designers and developers can work together on the same sources.

If you don't like it, you can find plenty of others on the web that may better suit your taste.

I wrote some tests myself that compares innerHTML and the DOM API. The DOM API was definitely faster.

Here are the results (I have tested on Firefix 3.6.8 and Chrome 5.0.375.125 beta): http://yilmazhuseyindevelopment.appspot.com/ois/images/ahh5aWxtYXpodXNleWluZGV2ZWxvcG1lbnRyEQsSCUltYWdlRGF0YRiptwUM

In the first test, I added one textnode to body of page 1000 times with the DOM API and innerHTML.

In the second test I created a table with the DOM API and inner HTML. Here is the actual code for my test:

<html>
    <head>
        <script type="text/javascript">
        window.onload = function(){
            var body = document.getElementsByTagName("body")[0];
            var text,table,tr,td;
            var count = 1000;
            console.time("DOM");
            for(var i = 0 ; i<count ; i++){
                    text = document.createTextNode("text");
                    body.appendChild(text);
                    body.removeChild(text)
            }
            console.timeEnd("DOM");
            console.time("innerHTML");
            for(var i = 0 ; i<count ; i++){
                body.innerHTML = "text";
                body.innerHTML = "";
            }
            console.timeEnd("innerHTML");
            //table structure
            console.time("DOM2");
            for(var i = 0 ; i<count ; i++){
                    table = document.createElement("table");
                    tr = document.createElement("tr");
                    td = document.createElement("td");
                    text = document.createTextNode("text");
                    table.appendChild(tr);
                    tr.appendChild(td);
                    td.appendChild(text);
                    body.appendChild(table);
                    body.removeChild(table);
            }
            console.timeEnd("DOM2");
            console.time("innerHTML2");
            for(var i = 0 ; i<count ; i++){
                body.innerHTML = "<table><tr><td>text</td></tr></table>";
                body.innerHTML = "";
            }
            console.timeEnd("innerHTML2");
        }
        </script>
    </head>

    <body/>
</html>

I guess that means the DOM API is better (performance wise) for modern browsers.

发布评论

评论列表(0)

  1. 暂无评论