什么时候使用基于DOM的Generation而不是使用strings / innerHTML / JQuery来生成DOM内容?

我想知道何时使用基于DOM的生成与.innerHTML或使用JQuery的.append方法追加字符串? 我在这里阅读了相关的post你应该使用innerHTML或逐个创建新元素来向DOM添加HTML吗? 但我仍然不确定每种方法的用例。这只是一个性能问题,我总是会选择一个而不是另一个?

假设表单是一个任意变量:

DOM生成

var div = document.createElement("div"), label = document.createElement("label"), input = document.createElement("input"); div.appendChild(label); div.appendChild(input); form.appendChild(div); 

JQuery的

  $(form).append("
")

第二个更具可读性,尽管它来自jQuery,它可以为您提供innerHTML。 在vanilla JS中,它会是这样的:

 form.insertAdjacentHTML("beforeend", "
");

…我认为甚至比jQuery更胜一筹。 虽然,你不应该担心性能 。 性能总是取决于要插入的节点数量 – 对于单个节点,HTML解析器比直接创建它们要慢,对于大型HTML字符串,本机解析器比脚本更快。 如果你真的担心性能,你需要测试,测试,测试(我会说你的应用程序有问题)。

然而,这两种方法之间存在很大差异:使用#1,您有三个引用DOM元素的变量 。 例如,如果你想在输入中添加一个事件监听器,你可以立即执行它,而不需要在form上调用querySelector,这会慢得多。 当然,在插入很多元素时 – 使用innerHTML – 你根本不需要这样做,因为你会使用委托事件来获得真正的性能提升。

请注意,您还可以使用jQuery将方法#1缩短为oneliner:

 var div, label, input; $(form).append(div=$("
").append(input=$(""),label=$("")));

我的结论:

  • 为了创建少数元素,DOM方法更清晰。
  • 大多数情况下,html字符串更具可读性。
  • 在标准情况下,两者都不会更快 – 基准测试结果差异很大。

就个人而言,我不喜欢(直接) innerHTML有几个原因,这些原因在这 两个答案中都有很好的概述。 此外,IE在表上有一个错误(请参阅IE中的无法在tbody上设置innerHTML )

一般来说,重复命中DOM比使用innerHTML交换大块HTML要慢得多。 我相信这有两个原因。 一个是回流。 浏览器必须重新计算潜在的各种元素的潜在布局影响。 另一方面,我相信,如果我错了,有人会纠正我,因为在浏览器的后编译执行环境中翻译正在进行的事情会有一些开销,其中渲染和布局状态正在被处理成一个对象你可以在JavaScript中使用。 由于DOM通常处于不断变化的条件下,因此每次都必须运行整个过程,几乎没有机会缓存​​任何类型的结果,即使您只是在不添加它们的情况下创建新元素(因为您很可能)想要预处理CSS规则以及诸如由于doctype之类的浏览器所处的’模式’之类的事情,可以事先在一般上下文中应用。

DOM方法允许您构建文档片段,并在不影响实际文档布局的情况下创建和附加HTML元素,这有助于避免不必要的重排。

但这里变得奇怪。

  • 将新HTML插入到没有任何内容的节点中 – 在很多(大多数是较旧的)浏览器中,接近领带或者innerHTML通常要快得多

  • 替换大量的HTML内容 – 实际上,当性能不太接近调用时,DOM方法往往会胜出。

基本上,innerHTML,如果它发臭,往往会在发生大量掉期的拆解过程中发臭。 在拆解时,DOM方法更好,但在创建新的HTML并直接注入时往往更慢,而在没有任何重大差异的情况下更换任何东西。

实际上有混合方法可以在您有需要时为性能做出非常了不起的事情。 我在一年多前使用过一次,并且对于延迟加载网格交换大量HTML内容与单独使用innerHTML相比,响应时间的改进给我留下了相当深刻的印象。 我希望我能找到一个值得信赖的人找到这个并在网上拼写它的人(作者,也写了很多RegEx的东西 – 不能谷歌我的生活)。

作为样式与性能的问题,我认为你应该避免反复调整实际的DOM节点结构,但事先在文档片段中构建HTML而不是使用innerHTML,这几乎是一个判断问题。 我个人最喜欢innerHTML,因为JS有很多强大的字符串方法可以快速将数据转换为HTML-ready字符串。 例如:

 var htmlStr = '
  • ' + arrayOfNames.join('
  • ') + '
';

单行是UL我可以直接分配给innerHTML。 使用正确的数据结构和简单的while循环构建完整的表几乎一样容易。 现在用尽可能多的LI构建相同的UL,使用DOM API的arrayOfNames的长度。 我真的想不起有很多很好的理由去做这件事。 innerHTML在最终被HTML 5规范采用之前成为事实上的标准。 它可能不适合基于节点的htmlElement对象调整DOM API的方法,但它function强大,可以帮助您保持代码简洁明了。 但是,我不太可能使用innerHTML来编辑和替换现有内容。 使用新的HTML中的数据,构建和交换比使用旧的HTML然后开始解析innerHTML字符串的属性等更安全,当你有方便的DOM操作方法并为此做好准备时。

你的主要性能问题可能应该是避免摧毁DOM的“实时”部分,但其余的我会留给人们作为风格和测试HTML生成的问题。 innerHTML已经并且多年来一直在HTML5工作草案中,但它在现代浏览器中非常一致。 在此之前的几年里,这也是事实上的规范,并且作为一种选择完全可行,因为在Chrome是新的之前,IMO,但这是一场大多数时候都在进行的辩论。

这只是一个表现问题。 选择最适合你的一个。

jsPerf充满了那些性能测试,就像这一个: 测试