【问题标题】:document.createElement Performance: Edge/IE11 too slow v/s Chrome/Firefoxdocument.createElement 性能:Edge/IE11 与 Chrome/Firefox 相比太慢
【发布时间】:2016-06-09 20:55:20
【问题描述】:

我维护的一些门户网站在运行时使用document.createElementdropdownlist 中创建options。在 IE10 之前一切都很好,但在 IE11Edge 突然性能急剧下降。

我创建了一个小提琴:https://jsfiddle.net/nitinph/ej5p65um/

请使用两组浏览器(IE11/Edge 和 Chrome/Firefox)运行它。您会注意到 IE11/Edge 需要 10 多秒,而 Chrome/Firefox 需要不到一秒。

我的问题是,是否有任何替代方式可以使用 document.createElement,以便在 IE11/Edge 中获得相似的性能。

var pTime = document.getElementById("pTime");
var d = new Date();
var n = d.getTime();
var ddl = document.getElementById("TestDDL");
for (var i = 0; i < 5000; i++) {
  var opt = document.createElement("option");
  opt.text = i;
  opt.value = i;
  ddl.options.add(opt);
}
d = new Date();
var n1 = d.getTime();
pTime.innerHTML = 'Time: ' + (n1 - n) / 1000 + ' sec.';
<select id="TestDDL">
</select>
<p id="pTime">
</p>

更新:感谢 @Squint,以下是在 IE11/Edge 中实现性能的四种替代方案:

var ddl = document.getElementById("TestDDL");

console.time("html")
var s = ""
for (var i = 0; i < 5000; i++) {
  s += "<option value='" + i + '>' + i + "</option>"
}
ddl.innerHTML = s;
console.timeEnd("html")

clearContent()

console.time("insertAdjacentHTML")
for (var i = 0; i < 5000; i++) {
	ddl.insertAdjacentHTML("beforeend", "<option value='" + i + '>' + i + "</option>")
}
console.timeEnd("insertAdjacentHTML")

clearContent()

console.time("frag")
var frag = document.createDocumentFragment();
for (var i = 0; i < 5000; i++) {
  var opt = document.createElement("option");
  opt.text = i;
  opt.value = i;
  frag.appendChild(opt);
}
ddl.appendChild(frag);
console.timeEnd("frag")

clearContent()

console.time("direct add")
for (var i = 0; i < 5000; i++) {
  var opt = document.createElement("option");
  opt.text = i;
  opt.value = i;
  ddl.options.add(opt);
}
console.timeEnd("direct add")


function clearContent() {
	while (ddl.firstChild) {
  	ddl.removeChild(ddl.firstChild)
  }
}

clearContent()

console.time("direct append")
for (var i = 0; i < 5000; i++) {
  var opt = document.createElement("option");
  opt.text = i;
  opt.value = i;
  ddl.appendChild(opt);
}
console.timeEnd("direct append")


function clearContent() {
	while (ddl.firstChild) {
  	ddl.removeChild(ddl.firstChild)
  }
}
<select id="TestDDL">
</select>
<p id="pTime">
</p>

【问题讨论】:

  • 请将所有相关代码直接放在问题中,而不是仅仅在其他网站上链接。
  • 此问题是否特定于 option 元素?还是使用.add() 方法?您是否尝试过在循环中附加到 documentFragment,然后将其附加到 select 元素?
  • @squint:此问题特定于 document.createElement。下面标记的答案是靶心。
  • @NP3 这与document.createElement 无关,它是options.add() 减慢你的代码。见a fiddle using appendChild
  • 我期待我的问题得到答复。无论如何,这里有 5 种不同的方式(包括你的方式)的比较。 jsfiddle.net/8ax5LLv2/1 选择你喜欢的任何一个(如果有的话),如果你愿意,可以把它放在答案中。

标签: javascript performance internet-explorer-11 microsoft-edge


【解决方案1】:

你可以用字符串构造元素 HTML:

var optionList = ["foo", "bar", "baz"];
var elementHTML = "";

for (var index = 0; index < optionList.length; index++) {
    elementHTML += "<option>" + optionList[index] + "</option>";
}

然后创建元素并设置innerHTML

var element = document.createElement("select");
element.innerHTML = elementHTML;

这通常会提供更好的性能,因为您只需调用一次document.createElement()。遗憾的是,直接动态 DOM 处理通常很慢,建议不要这样做。

【讨论】:

  • 我支持你,因为这也解决了我的问题。但是.appendChild 似乎是一个更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 2021-04-02
  • 1970-01-01
  • 2020-01-12
  • 2019-04-18
  • 1970-01-01
  • 2020-11-19
  • 2014-11-19
  • 1970-01-01
相关资源
最近更新 更多