哪个更好:字符串html生成或jquery DOM元素创建?

Ed *_*mes 15 jquery dom-manipulation

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

我的问题是,更好/首选这样做:

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

要么

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

Nic*_*ver 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
Run Code Online (Sandbox Code Playgroud)

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

您可以通过上面的内容看到,由于缓存的片段更复杂,缓存越多就会产生影响.在第一个测试中,这是没有条件清理的示例,DOM丢失,因为在此测试中有很多小操作(在我的机器上,但您的比率应该大致相同):HTML联系人: 25ms,DOM操作:149ms.

但是,如果您可以缓存复杂片段,则可以获得不重复创建这些DOM元素的好处,只需克隆它们即可.在第二个测试中,DOM胜出,因为虽然HTML方法创建了530次 DOM元素集合,但第二个缓存方法只创建一次,并将其克隆5000次.在此测试中:HTML Concat:282ms,DOM操作:157ms.

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

  • 很想知道为什么要对此进行投票.这个人错了吗?启发我们. (2认同)

kne*_*ola 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');
Run Code Online (Sandbox Code Playgroud)

结论是,只有当您计划反复复制相同的HTML片段时,DOM缓存才能更快地运行.如果没有使用字符串连接.

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