JavaScript:使用 innerHTML 或(大量)createElement 调用来添加复杂的 div 结构更好吗?

IT技术 javascript dom
2021-02-28 23:39:23

我正在研究一个需要为一组 ~100 个元素中的每个元素创建一个复杂的 div 块的问题。

除了内容之外,每个单独的元素都是相同的,它们看起来(在 HTML 中)是这样的:

<div class="class0 class1 class3">
<div class="spacer"></div>
<div id="content">content</div>
<div class="spacer"></div>
<div id="content2">content2</div>
<div class="class4">content3</div>
<div class="spacer"></div>
<div id="footer">content3</div>
</div>

我可以:

1) 像innerHTML字符串连接一样创建所有元素以添加内容。

2) 使用createElement,setAttributeappendChild创建并添加每个 div。

选项 1 下载的文件稍小,但选项 2 的渲染速度似乎稍快。

除了性能之外,是否有充分的理由选择一条路线或另一条路线?我应该测试任何跨浏览器问题/性能小精灵?

...或者我应该尝试模板和克隆方法吗?

非常感谢。

6个回答

两者都不。使用像 jQuery、Prototype、Dojo 或 mooTools 这样的库,因为这两种方法都充满了麻烦:

主要 javascript 库的作者花费了大量时间并拥有完整的错误跟踪系统,以确保当您调用他们的 DOM 修改工具时,它们确实可以工作。

如果你正在编写一个库来与上述工具竞争(如果你是,祝你好运),那么我会选择基于性能的方法,并且innerHTML过去总是胜出,因为innerHTML是一个本机方法,可以肯定的是它会保持最快的速度。

@user949300 您在 2020 年推荐什么?
2021-05-01 23:39:23
由于您引用的所有这些库到 2018 年都已基本过时,因此它们的竞争对手确实有“好运”。
2021-05-17 23:39:23

取决于什么对你来说“更好”。

表现

从性能的角度来看,createElement+appendChild 胜出很多。看看我在比较两者时创建的这个 jsPerf并且结果打在脸上。

innerHTML: ~120 ops/sec
createElement+appendChild: ~145000 ops/sec

(在我的装有 Chrome 21 的 Mac 上)

此外,innerHTML 会触发页面重排。

在 Ubuntu 上使用 Chrome 39测试得到类似的结果

innerHTML: 120000 ops/sec
createElement: 124000 ops/sec

可能会进行一些优化。在带有基于 QtWebkit 的浏览器 Arora(wkhtml 也 QtWebkit)的 Ubuntu 上,结果是

innerHTML: 71000 ops/sec
createElement: 282000 ops/sec

似乎平均而言 createElement 更快

可维护性

从可维护性的角度来看,我相信字符串模板对您有很大帮助。我使用Handlebars(我喜欢)或Tim(对于需要最小足迹的项目)。当您“编译”(准备)您的模板并准备将其附加到 DOM 时,您可以使用 innerHTML 将模板字符串附加到 DOM。我为避免回流所做的技巧是为包装器创建元素,并在该包装器元素中,将模板与innerHTML 一起放置。我仍在寻找一种完全避免使用innerHTML 的好方法。

兼容性

您不必担心,这两种方法都得到了广泛的浏览器的完全支持(与 altCognito 所说的不同)。您可以检查createElementappendChild 的兼容性图表

您的 jsPerf 链接已损坏。
2021-05-03 23:39:23

altCognito 提出了一个很好的观点 - 使用库是要走的路。但如果是手工完成,我会使用选项 #2 - 使用 DOM 方法创建元素。它们有点丑,但你可以制作一个元素工厂函数来隐藏丑陋。连接 HTML 字符串也很丑陋,但更有可能出现安全问题,尤其是 XSS。

不过,我绝对不会单独附加新节点。我会使用 DOM DocumentFragment。将节点附加到 documentFragment 比将它们插入实时页面要快得多。当你完成你的片段的构建后,它就会被一次性插入。

John Resig 解释得比我好得多,但基本上你只是说:

var frag = document.createDocumentFragment();
frag.appendChild(myFirstNewElement);
frag.appendChild(mySecondNewElement);
...etc.
document.getElementById('insert_here').appendChild(frag);

就我个人而言,我使用 innerHTML 是因为它是我所习惯的,对于这样的事情,W3C 方法给代码添加了很多混乱。

然而,这只是减少 div 数量的一种可能方法,您是否有任何原因使用间隔元素而不是仅编辑内容 div 上的边距?

OP 的问题应该在对原始问题的评论中,而不是您的答案的一部分。
2021-04-27 23:39:23

我认为他们之间没有太多选择。在过去(IE6、FF1.5),innerHTML 更快(benchmark),但现在在大多数情况下似乎没有明显差异。

根据Mozilla 开发人员的说法docs在某些情况下,innerHTML 行为因浏览器而异(特别是在表格内),因此 createElement 将为您提供更多一致性 - 但 innerHTML 通常较少输入。