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