15

好的,我正在我当前的项目中重写一些 vanilla JS 函数,并且我正处于为工具提示等生成大量 HTML 的地步。

我的问题是,这样做更好/更喜欢这样做:

var html = '<div><span>Some More Stuff</span></div>';
if (someCondition) {
    html += '<div>Some Conditional Content</div>';
}
$('#parent').append(html);

或者

var html = $('<div/>').append($('<span/>').append('Some More Stuff'));
if (someCondition) {
    html.append($('<div/>').append('Some conditionalContent');
}
$('#parent').append(html);

?

4

4 回答 4

36

从性能的角度来看:这取决于.

在您的简短示例中,附加文本更快,因为您实际上直到最后都没有创建任何 DOM 元素。但是,如果您经常这样做,那么字符串连接所增加的时间与缓存文档片段的性能就会相加。

当您执行$(html)jQuery 将其缓存为文档片段时(假设字符串为 512 字节或更少),尽管如果您只是缓存并没有太多收益$("<div />")......但是如果您这样做数千次,则有一个可衡量的影响,随着字符串变长,字符串连接变得更加昂贵,缓存的文档片段成本相当稳定。

更新:这里有一些简单的例子来了解我的意思,在这里使用 firebug 来获取控制台时间:

你可以自己运行它:http: //jsfiddle.net/Ps5ja/

console.time('concat');
var html = "";
for(var i = 0; i < 500; i++) {
    html += '<div><span>Some More Stuff</span></div>';
    html += '<div>Some Conditional Content</div>';
}
var elem = $(html);
console.timeEnd('concat'); //25ms

console.time('DOM');
var parent = $("<div />")
for(var j = 0; j < 500; j++) {
    parent.append($('<div/>').append($('<span/>', {text :'Some More Stuff'})));
    parent.append($('<div/>',{ text: 'Some conditionalContent' }));
}
console.timeEnd('DOM'); //149ms

console.time('concat caching');
var html = "";
for(var i = 0; i < 5000; i++)
    html += '<div><span>Some More Stuff</span></div><div>Some Conditional Content</div>';
var elem = $(html);
console.timeEnd('concat caching'); //282ms

console.time('DOM caching');
var parent = $("<div />")
for(var j = 0; j < 5000; j++)
    parent.append('<div><span>Some More Stuff</span></div><div>Some Conditional Content</div>');
console.timeEnd('DOM caching'); //157ms

注意:var elem = $(html);在字符串测试中,我们最终会创建相同的 DOM 元素,否则您会将字符串连接与实际的 DOM 创建进行比较,这几乎不是公平的比较,也不是很有用:)

从上面可以看出,缓存的fragment越复杂,缓存的影响越大。在第一个测试中,这是您的示例,没有稍微清理一下条件,DOM 丢失,因为有很多小操作正在进行,在此测试中(在我的机器上,但您的比率应该大致相同):HTML 联系人: 25毫秒DOM 操作:149 毫秒

但是,如果您可以缓存复杂的片段,您就不会重复创建这些 DOM 元素,只需克隆它们即可。在第二个测试中,DOM 胜出,因为虽然 HTML 方法创建了5000 次该 DOM 元素集合,但第二个缓存方法只创建了一次,并克隆了 5000 次。在这个测试中:HTML Concat: 282ms , DOM Manipulation: 157ms

我意识到这并不是直接回答您的问题,但根据评论,似乎对性能有些好奇,所以只需提供一些您可以看到/测试/玩的东西。

于 2010-04-22T11:36:11.800 回答
5

我测试了 Nick Craver 提交的代码,发现只有在元素内容不变的情况下,DOM 缓存才能更快地工作。但是,如果您在 for 循环的每次迭代中更改字符串,则速度会急剧下降

这是修改后的相同代码(在 Fiddle 上测试:http: //jsfiddle.net/Ps5ja/42/

console.time('concat');
var html = "";
for(var i = 0; i < 500; i++) {
    html += '<div><span>Some More Stuff</span></div>';
    html += '<div>Some Conditional Content</div>';
}
var elem = $(html);
console.timeEnd('concat');

console.time('DOM');
var parent = $("<div />")
for(var j = 0; j < 500; j++) {
    parent.append($('<div/>').append($('<span/>', {text :'Some More Stuff'})));
    parent.append($('<div/>',{ text: 'Some conditionalContent' }));
}
console.timeEnd('DOM');

console.time('concat caching');
var html = "";
for(var i = 0; i < 10000; i++)
    html += '<div><span>Some More Stuff</span></div><div>Some Conditional Content'+i+'</div>';
var elem = $(html);
console.timeEnd('concat caching');

console.time('concat array.join');
var arr = [];
for(i = 0; i < 10000; i++)
    arr.push('<div><span>Some More Stuff</span></div><div>Some Conditional Content'+i+'</div>');

var elem = $(arr.join(''));
console.timeEnd('concat array.join');

console.time('DOM caching - NO modification');
var parent = $("<div />")
// here the contained text is unchanged in each iteration
for(var j = 0; j <10000; j++)
    parent.append('<div><span>Some More Stuff</span></div><div>Some Conditional Content</div>');
console.timeEnd('DOM caching - NO modification');

console.time('DOM caching with modification');
var parent = $("<div />")
// here the contained text is modified in each iteration
// (the value od J is appended to the text)
for(var j = 0; j <10000; j++)
    parent.append('<div><span>Some More Stuff</span></div><div>Some Conditional Content'+j+'</div>');
console.timeEnd('DOM caching with modification');

结论是,只有当您计划一遍又一遍地复制相同的 HTML 片段时,DOM 缓存才能更快地工作。如果不使用字符串连接。

我没有发现使用 Array.join 方法的任何速度优势。但是我还没有彻底测试过(如果迭代次数更大,可能会发生变化)。

于 2013-06-11T12:37:02.047 回答
2

支持 DOM 操作优于 innerHTML 方法。一方面,DOM 操作将正确处理需要使用 innerHTML 转义的字符。另一方面,它通常更快,有时更快

于 2010-04-22T11:38:26.383 回答
0

一般来说,如果我要生成很多 html,我会将它们全部收集在一个字符串中,然后让浏览器一次性生成所有元素。

如果涉及很多条件或循环,那么您可能希望使用 Array.join() 而不是使用 + 进行字符串连接。使用字符串连接,浏览器会生成大量的中间字符串,这些字符串可能非常慢;Array.join() 跳过所有这些中间字符串。对于这些情况,我会做类似的事情:

var html = ['<div><span>Some More Stuff</span></div>'];
for (var i = 0; i < 1000; i++) {
    html.push('<div>Some Loop Content</div>');
}
$('#parent').append(html.join(''));
于 2010-04-23T02:02:50.237 回答