用jQuery动态生成html的正确方法

我发现这个话题有一些不同和矛盾的答案。

我正在构建一个基于jQuery动态生成的HTML的应用程序,基于从底层API以JSON数据形式获取的结果。

我的一些同事(个人)告诉我,最好的办法是做这样的事情:

var ul = $("<ul>").addClass("some-ul");
$.each(results,function(index) {
  ul.append($("<li>").html(this).attr("id",index));
});
$("body").append($("<div>").attr("id","div-id").addClass("some-div").append(ul));

等等
我被告知的原因是“直接更新DOM而不是解析html来实现它”。

但是,我看到很多这样的代码(同样的例子):

var toAppend = '<div class="some-div" id="div-id"><ul>';
$.each(results,function(index) {
  toAppend += '<li id="' + index + '">' + this + '</li>';
});
toAppend += '</ul></div>'

我个人认为不那么优雅 – 但是更好吗?我把这个问题搞了几分钟,发现了this article.基本上,它是通过使用字符串连接来提高性能 – 我的“第二种方式”。

这篇文章的主要问题是它已经在2009年发布,并且讨论了jQuery版本是1.3。今天,目前的版本是1.6.4版本,它的行为可能会有很大的不同。这是关于我已经找到的大多数文章的问题,我也对他们的信誉有些怀疑。

这就是为什么我决定在这里发布问题,问 – 根据性能生成DOM的方法实际上是正确的?

重要编辑:

我已经写了一个基准测试,哪种方法更好地考虑性能

jsFiddle – 级联版本

jsFiddle – 阵列加入版本

码:

var text = "lorem ipsum";
var strings = $("#strings");
var objects = $("#objects");
var results = $("#results");

// string concatenation
var start = new Date().getTime();
var toAppend = ['<div class="div-class" id="div-id1"><ul class="ul-class" id="ul-id1">'];
for (var i = 1; i <= 20000; i++) {
    toAppend[i] = '<li class="li-class" id="li-id1-' + i + '">' + text + '</li>';
}
toAppend[i++] = '</ul></div>';
results.append(toAppend.join(""));
strings.html(new Date().getTime() - start);

// jquery objects
var start = new Date().getTime();
var ul = $("<ul>").attr("id","ul-id2").addClass("ul-class");
for (var i = 0; i < 20000; i++) {
    ul.append($("<li>").attr("id","li-id2-" + i).addClass("li-class"));
}
results.append($("<div>").attr("id","div-id2").addClass("div-class").append(ul));
objects.html(new Date().getTime() - start);

看起来,使用字符串比使用jQuery对象和方法更快(在Firefox 7中约7次)。但是我可能错了,特别是如果这个“基准”代码中有任何错误性能下降的错误。随意进行任何更改。

注意:由于前面提到的文章而不是实际的连接,我使用了Array join。

编辑:基于@hradac的建议,我在基准测试中使用了实际的字符串连接,实际上改进了时代。

解决方法

首先,这种微基准测试几乎从来没有告诉你你想要真正知道什么。其次,你的基准是多样的,而不是等同的。例如,您的第一个示例生成如下所示的行:
<li class="li-class" id="li-id1-493">lorem ipsum</li>

和你的第二行这样:

<li id="li-id2-0" class="li-class"></li>

注意不同的元素顺序和缺少“lorem ipsum”文本。也没有任何尝试清除测试之间的结果div,以避免性能问题,因为第一个20K的结果已经在那里。

但是除了这些问题之外,还有一个问题,“这样的表现真的打乱了客户端的用户体验吗?真的吗?您以这样的方式呈现这样的文本数量,您在呈现文本的替代方法之间看到明显的区别?

我会回到别人说的话,使用模板引擎。最快的是确实很快,甚至有预编译选项,以允许您重新渲染相同的模板并获得快速的结果。所以不要相信我。相反,相信一个示威。这是我的jsfiddle来演示应该替换jQuery模板引擎的新JsRender库的性能

http://jsfiddle.net/LZLWM/10/

注意:JsRender可能需要几秒钟才能加载到小提琴中。这是因为我把它从GitHub中直接拉出来,这不是GitHub特别擅长的。我不建议在实践中。它不会改变时间,但是,直到jsfiddle开始将模板引擎作为选项,才有必要。

请注意,第二个例子更接近现实世界的示例,使用JSON作为起始点,生成20,000行,与您最快的测试(我的机器上的差距<50ms)大致相同。还要注意,代码和模板都比任何混乱的附件和字符串连接都会变得更加清晰和易于使用。我需要多少次迭代才能让我的模板正确与你在做什么? 使用简单的东西,并且在可能甚至不需要的时候停止在这个微优化级别上浪费时间。而是使用这样的模板(或任何其他几个好的模板引擎),并确保您已经过期的标题已打开,您正在使用CDN,您的服务器上已经启用了gzip压缩等。 YSlow告诉你要做的事情,因为这将彻底淹没你所看到的东西的影响。

相关文章

页面搜索关键词突出 // 页面搜索关键词突出 $(function () {...
jQuery实时显示日期、时间 html: &lt;span id=&quot...
jQuery 添加水印 &lt;script src=&quot;../../../.....
中文:Sys.WebForms.PageRequestManagerParserErrorExceptio...
1. 用Response.Write方法 代码如下: Response.Write(&q...
Jquery实现按钮点击遮罩加载,处理完后恢复 思路: 1.点击按...