用于解压缩数组的JavaScript循环速度慢(>;两分钟)

用于解压缩数组的JavaScript循环速度慢(>;两分钟),javascript,arrays,Javascript,Arrays,我有一些JSON数据来自JavaScript通过XHR接收的查询。这是我收到的数据的结构: [{ "date": "17 February 1806", "dinnerID": "h1806-02-17a", "note": "...", "diners": { "name": [ [

我有一些JSON数据来自JavaScript通过XHR接收的查询。这是我收到的数据的结构:

[{
  "date": "17 February 1806",
  "dinnerID": "h1806-02-17a",
  "note": "...",
  "diners": {
    "name": [
      [
        "Lord Gilbert Elliot-Murray-Kynynmound"
      ],
      [
        "Humble Mr  Elliot"
      ],
      [
        "Mr  Allen"
      ],
      [
        "Lady  Holland"
      ],
      [
        "Lord  Holland"
      ]
    ]
  }
}
[etc...]
]
迭代我的结果可以得到一些结果,比如200/300。但是,如果我有一个结果更多的查询(可能会达到1000个左右),那么在收到XHR响应后,浏览器会在两分钟以上没有响应。您可以在控制台中看到记录的条目一个接一个地“缓慢”滚动。这是一个结构性的限制,还是我能做些什么

// for (let i = 0; i < result.length; i++){ // These three variants
// for (let [i, val] of Object.entries(result)) { // don't make n appreciable difference
for (var dinner of result) { // to the time the loops takes to complete.
document.getElementById("resultSearch").innerHTML += '<button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#modal-' + result.dinnerID + '">' + result.date + '</button>'
console.log(dinner)
}
在最后两个指令中是否也要使用
appendChild
?在这种情况下,参数1不是对象

编辑2和工作代码

我通过将
appendChild
代码放入循环中解决了这个问题:

let fragmentLinks = document.createDocumentFragment();
fragmentLinks.appendChild(button);
targetLinks.append(fragmentLinks)

尽管我在每次迭代中调用
appendChild
,但与最初的>分钟相比,这只需要不到一秒钟的时间。因此,我想,
fragment
确实让事情变得更快。

DocumentFragment并不比innerHTML快,请在循环之外使用
.innerHTML

var htmlString = ''; 

for (var dinner of result) {
  htmlString += '<button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#modal-' + result.dinnerID + '">' + result.date + '</button>'
}

document.getElementById("resultSearch").innerHTML += htmlString;
let fragmentLinks = document.createDocumentFragment();
fragmentLinks.appendChild(button);
targetLinks.append(fragmentLinks)
var htmlString='';
for(结果的var){
htmlString+=''+结果.date+''
}
document.getElementById(“resultSearch”).innerHTML+=htmlString;

多亏了@GrahamRitchie,我通过将appendChild代码放入循环中解决了这个问题

var htmlString = ''; 

for (var dinner of result) {
  htmlString += '<button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#modal-' + result.dinnerID + '">' + result.date + '</button>'
}

document.getElementById("resultSearch").innerHTML += htmlString;
let fragmentLinks = document.createDocumentFragment();
fragmentLinks.appendChild(button);
targetLinks.append(fragmentLinks)

尽管我在每次迭代中都调用appendChild,但与初始>分钟相比,这只需要不到一秒钟的时间。所以,我想,fragment确实让事情变得更快。

您的性能问题有两个方面,首先,将每个条目记录到控制台会降低速度,所以我不会这样做。更重要的是,一个接一个地向DOM中添加元素会使性能受到影响。看一看,让我们构建一个复杂的结构,而不必在每一步都将其添加到DOM中。一旦构建完成,您就可以将完全构建的项添加到DOM中,这将大大加快速度。谢谢,我在注意到性能问题后添加了console.log只是为了进行测试。当然,我会删除它,谢谢您指出这一点。我不知道documentFragment的事,我来看看。如果你想写一个更清晰的答案,并且它对我有效,那么我会接受它。另一个可能加快你的过程的事情是不要在每次迭代中查询元素。在循环外查询它一次,然后像这样使用它
constresultsearch=document.getElementById(“resultSearch”)
。然后在你的循环中使用
resultSearchem.innerHTML+=…
。我会让其他人窃取荣誉,因为我不在电脑上工作,所以很难将代码示例放在一起等(但如果没有人回答,我会在稍后为你写下答案和代码示例)。最后要注意的一点是,
.innerHTML+=
在大多数情况下都不是最好的主意,因为它会破坏您设置的事件处理程序。如果您正在添加字符串以外的任何内容,例如
,并使用
.createElement
等在JS中构建元素,请改用。谢谢@GrahamRitchie,我更新了我的问题,因为我在附加模态时遇到了一些问题,甚至使用
.createElement
。谢谢,这看起来很有希望。我遇到的一个问题是:我还在为每个结果创建一个模式:
divModal.innerHTML=modal;modals+=divModal
在循环内部,然后
document.getElementById(“resultSearch”).innerHTML+=modals
在循环外部。它适用于链接,不适用于情态动词。它输出一系列的
[object htmldevelment]
“文档片段不比innerHTML快”-您曾经测试过它吗?我发现现在快多了,但我可能错过了什么?我一直认为这只是老派浏览器,因为当我在该页面上测试示例时,在Chrome和FireFox中使用documentFragment的速度要快500倍,但该示例可能因为克隆节点而存在缺陷?我同意@GrahamRitchie的观点,它的速度非常快(请参阅我更新的问题)。在我的电脑中,innerHTML使用了2-3秒,而documentfragment 3-4和innerHTML使用的代码更少@HBMCS也许你可以试试
…innerHTML+=modals.outerHTML
我的意思是毫秒而不是秒