.append VS .html VS .innerHTML 性能

IT技术 javascript jquery
2021-03-02 00:39:37

该站点在 3 种不同方法之间进行了测试,它似乎.html是最快的,其次是.append. 其次是.innerHTML有人可以向我解释原因吗?

是对三种方法进行比较站点

我已经阅读了这个相关的SO 问题,但我并没有真正理解给定的答案,并且该问题并没有对.innerHtml.

我不明白以下部分:

创建了一个临时元素,我们称之为 x。x 的innerHTML 设置为您传递的HTML 字符串。然后 jQuery 将每个生成的节点(即 x 的 childNodes)转移到一个新创建的文档片段,然后它会在下一次缓存。然后它将片段的 childNodes 作为一个新的 DOM 集合返回。请注意,它实际上比这复杂得多,因为 jQuery 进行了大量跨浏览器检查和各种其他优化。例如,如果您只传递<div></div>给 jQuery(),jQuery 将采用快捷方式并简单地执行 document.createElement('div')。

有人可以简化这个吗?

6个回答

这三个对我来说都很慢。在每次迭代中修改 dom 很慢。

http://jsperf.com/jquery-append-vs-html-list-performance/24

我刚刚在那里添加了一个新测试:

var html = [];
for (var i = 0; i < len; i++) {
  html.push('<div>Test ' + i + '</div>');
}

document.getElementById('list').innerHTML = html.join('');

这又快多了。:)

我在 Firefox 中的方法是 26k Ops/sec vs 1,000、10,000 和 13

在此处输入图片说明

@Bart - 我们在使用模板框架构建 50 列 x 200 行表客户端时遇到了大量问题。我从destroyallsoftware.com/talks/wat得到了连接整个表格的想法我们从 5-10 秒的渲染变成了即时渲染。(虽然 IE 7 仍然需要大约 2 秒)
2021-04-18 00:39:37
嗯,看到结果了。从来不知道阵列哪里那么快。
2021-04-22 00:39:37
这很让人佩服。顺便说一下,那次谈话非常有趣:-D
2021-05-16 00:39:37
谢谢!这一优势适用于更长和更复杂的数组(例如带有长字符串的数组)。我进行了此切换,发现我的性能提高了 600 多倍 - 1,800 毫秒与 3 毫秒。
2021-05-17 00:39:37

那个基准毫无value。innerHTML总是比 DOM 操作快。

jQuery看起来更快,因为它首先准备一个包含所有 HTML 的字符串,而其他人每次迭代都执行一个操作。还要注意 jQuery.html() 会innerHTML尽可能使用

来自基准测试的 jQuery

var html = '';
for (var i = 0; i < len; i++) {
  html += '<div>Test ' + i + '</div>';
}

$('#list').html(html);

来自基准测试的innerHTML

var list = document.getElementById('list');
for (var i = 0; i < len; i++) {
  list.innerHTML = list.innerHTML + '<div>Test ' + i + '</div>';
}

innerHTML如果它是这样写的那么测试会快很多:

var list = document.getElementById('list');
var html = '';

for (var i = 0; i < len; i++) {
    html += '<div>Test ' + i + '</div>';
}

list.innerHTML = html;

http://jsben.ch/#/yDvKH

@MuhamadAkbarBinWidayat 是的。本机代码总是更快。jQuery 自己使用它。除了innerHTMLDOM 操作之外,操作文档的余地并不多。
2021-04-17 00:39:37
所以Javascript函数比jQuery更高效?
2021-04-18 00:39:37
要进行适当的比较,除了要比较的确切内容外,您应该保持所有内容相同,这与我见过的许多 jsperf 比较不同。这是一个简单、更准确的性能比较:jsperf.com/innerhtml-vs-html-vs-empty-append
2021-04-18 00:39:37
@invisal 修正了:P
2021-04-21 00:39:37
请添加style='display:none'这样看起来更好:jsperf.com/jquery-html-vs-innerhtml-the-better-way/2
2021-04-29 00:39:37

如何.html使用大量额外代码.innerHTML更快这里在 jQuery 中实现(直接取自 jQuery 文件)。.html.innerHTML.html

html: function( value ) {
    return jQuery.access( this, function( value ) {
        var elem = this[0] || {},
            i = 0,
            l = this.length;

        if ( value === undefined ) {
            return elem.nodeType === 1 ?
                elem.innerHTML.replace( rinlinejQuery, "" ) :
                undefined;
        }

        // See if we can take a shortcut and just use innerHTML
        if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
            ( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
            ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
            !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {

            value = value.replace( rxhtmlTag, "<$1></$2>" );

            try {
                for (; i < l; i++ ) {
                    // Remove element nodes and prevent memory leaks
                    elem = this[i] || {};
                    if ( elem.nodeType === 1 ) {
                        jQuery.cleanData( getAll( elem, false ) );
                        elem.innerHTML = value;
                    }
                }

                elem = 0;

            // If using innerHTML throws an exception, use the fallback method
            } catch(e) {}
        }

        if ( elem ) {
            this.empty().append( value );
        }
    }, null, value, arguments.length );
}
有趣的是,这个答案实际上提出了一个带有解释的问题!:)
2021-05-11 00:39:37

正如 Bart 所说,innerHTML 总是比 DOM 操作快

我正在测试 hyperHTML,所以我想我要分享我的结果。实际上,我最初并没有在 CodePen 中运行我的基准测试,并且有一个有趣的区别,即 jQuery 时间更接近于在 CodePen 中运行的 innerHTML。

铬合金:
创建片段 312.80 毫秒  
超HTML 253.10 毫秒     
内部 HTML 62.70 毫秒   
$.append 183.40 毫秒

Chrome(扩展程序关闭): 
创建片段 225.10 毫秒 
超HTML 139.80 毫秒 
内部HTML 47.80 毫秒 
$.append 170.90 毫秒

火狐: 
创建片段 141 毫秒 
超HTML 84 毫秒 
内部 HTML 25 毫秒 
$.append 90 毫秒

边缘: 
创建片段 422.50 毫秒 
超HTML 184.60 毫秒 
内部HTML 44.00 毫秒 
$.append 1629.69 毫秒

IE11: 
创建片段 1180.29 毫秒 
hyperHTML 13315.59 ms //缓慢回退,IE 很烂 
内 HTML 125.70 毫秒 
$.append 2382.49 毫秒

我认为这一切都很简单。JavaScript 在解析和创建元素方面不如浏览器快,因为浏览器是机器特定的编译代码。没有比仅仅移交 HTML 并让浏览器不间断地完成工作做得更好的了。

某些性能差异可能是由于 XSS 检查造成的,这看起来很谨慎。

function runbench(){
  var data = [];
  for (var i = 0; i < 10001; i++) {
      data.push("<span>" + i + "</span>");
  }

  var perf=[];
  var t0 = performance.now();
  var c = document.createDocumentFragment();
  for (var i = 0; i < 10001; i++) {
      var e = document.createElement("span");
      e.innerHTML = data[i];
      c.appendChild(e);
  }
  document.querySelector('#createFragment').appendChild(c);
  document.querySelector('#createFragment').classList='done';
  var t1 = performance.now();
  perf.push(t1-t0);

  var t0 = performance.now();
  document.querySelector('#innerHTML').innerHTML = data.join('');
  document.querySelector('#innerHTML').classList='done';
  var t1 = performance.now();
  perf.push(t1-t0);

  var t0 = performance.now();
  $('#jqhtml').html(data.join(''));
  document.querySelector('#jqhtml').classList='done';
  var t1 = performance.now();
  perf.push(t1-t0);

  var t0 = performance.now();
  $('#jqappend').append(data.join(''));
  document.querySelector('#jqappend').classList='done';
  var t1 = performance.now();
  perf.push(t1-t0);

  var t0 = performance.now();
  hyperHTML.bind(document.querySelector('#hyperHTML'))       
  `${data.map(function (item) {
      return "<span>" + item + "</span>";
  })}`;
  document.querySelector('#hyperHTML').classList='done';
  var t1 = performance.now();
  perf.push(t1-t0);

  var stats = [];
  stats.push("<table>")
  stats.push("<tr><td>createFrag: </td><td>" + perf[0].toFixed(2) + "</td></tr>");
  stats.push("<tr><td>innerHTML: </td><td>" + perf[1].toFixed(2) + "</td></tr>");
  stats.push("<tr><td>$.html: </td><td>" + perf[2] .toFixed(2) + "</td></tr>");
  stats.push("<tr><td>$.append: </td><td>" + perf[3] .toFixed(2) + "</td></tr>");
  stats.push("<tr><td>hyperHTML: </td><td>" + perf[4].toFixed(2) + "</td></tr>");
  stats.push("</table>");
  $('#performance').html(stats.join(''));
  document.querySelector('#performance').classList='done';
}

https://codepen.io/jwhooper/pen/GzKwMV

我认为使用建议@Brat 的innerHTML 更快。

在创建循环和附加字符串时,最好先使用变量。它是让你的表现更好。

好的代码:

var html = '';
for (var i = 0; i < len; i++) {
  html += '<div>Test ' + i + '</div>';
};
$('#list').append(html);

效率不高的代码:

for (var i = 0; i < len; i++) {
  var html = '<div>Test ' + i + '</div>';
  $('#list').append(html);
}

例如:http : //jsben.ch/#/yDvKH

我最后测试的一个更快的测试是在循环外有一个数组 var html = [] 并在循环内使用 html.push("<td>...</td>") 并且一旦循环结束, 使用 element.innerHTML = html.join("") 尝试用这个运行一个测试,它的数量级更快
2021-05-04 00:39:37