快速与容器内的大量元素进行交互(DOM,javascript)

Mir*_*ror 9 html javascript dom

所以我在容器div中有大量的div(4000-5000)[每个包含跨度,锚点,图像等],基本上我将它们的显示设置为none或基于条件阻止.这确实需要一些时间.

在我搜索更快的内容时,我遇到了这个页面https://developers.google.com/speed/articles/javascript-dom,解决方法是从DOM中删除容器div并通过getElementsByTagName迭代包含的元素.

/**
 * Remove an element and provide a function that inserts it into its original position
 * @param element {Element} The element to be temporarily removed
 * @return {Function} A function that inserts the element into its original position
 **/
function removeToInsertLater(element) {
  var parentNode = element.parentNode;
  var nextSibling = element.nextSibling;
  parentNode.removeChild(element);
  return function() {
    if (nextSibling) {
      parentNode.insertBefore(element, nextSibling);
    } else {
      parentNode.appendChild(element);
    }
  };
}


function updateAllAnchors(element, anchorClass) {
  var insertFunction = removeToInsertLater(element);
  var anchors = element.getElementsByTagName('a');
  for (var i = 0, length = anchors.length; i < length; i ++) {
    anchors[i].className = anchorClass;
  }
  insertFunction();
}
Run Code Online (Sandbox Code Playgroud)

问题是我无法使用提供的解决方案,因为我需要通过其ID访问子元素,我不能这样做,因为元素已从DOM中删除.有没有办法实现这个目标?

我还尝试删除容器div并将其附加到文档片段,但是当它们位于documentfragment中时,仍然无法通过ID访问5000个元素

最后,我也尝试了这个:

document.getElementById("CONTAINERDIV").style.display = "none";

//iterate through the 5000 children divs and change their classname

document.getElementById("CONTAINERDIV").style.display = "block";
Run Code Online (Sandbox Code Playgroud)

因为我希望它不会在每次迭代时触发回流,但这似乎并没有提供所需时间的改进.

有没有人对此有任何想法?

小智 9

我会尝试按要求提供来源.

第一个解决方案 - 最好的解决方案
根据这个网站:具有100万条记录的JavaScript网格
你可以学到几个重要的东西:

  1. 大量DOM节点使渲染变慢
  2. JavaScript数组可以处理大型数据集
  3. 通过大型阵列循环很快
  4. 通过向Array.sort()提供自定义函数来对数组进行排序很快
  5. eval()很慢,不应该在大循环中使用

所以,我建议你构建一个数组来快速处理你的元素.

第二个解决
方案从这个站点获取的另一个解决方案:在JavaScript中处理大量数据
将使用超时(听起来很奇怪)来提高处理程序的速度.
这个想法来自Book:JavaScript Ninja的秘密


Krz*_*ski 5

如果你只想显示/隐藏,不改变div的DOM中的任何内容,你知道所有ID,我认为,存档的最好(最快)方法是准备<style />元素并将其附加到DOM.样式el应包含所有ID和正确显示.迭代ID并将其添加到CSS字符串,然后创建<style />元素并将字符串追加到它.这应该适合你.


cba*_*ram 3

显示无/块是昂贵的。从我提高交易网络平台性能的日子来看,我可以推荐的一种技术,尤其是在旧版浏览器中表现出色的技术是使用相对位置,并使用负左值将其从屏幕上拉出。当然,根据您的实现,您可能还想将高度设置为 0px 或研究绝对位置的可能性。核心概念仍然是,您只需将元素从屏幕上拉下来即可。好消息是隐藏的元素仍然在 DOM 中,您可以访问它们。

div {
  position: relative;
  left: 0px;
}
div.hide {
  left: -4096px;
  height: 0px;
} 
Run Code Online (Sandbox Code Playgroud)

看看这两个小提琴,它们创建 10K 行并切换(隐藏/显示)奇数行:

FIDDLE 使用 Display none/block

FIDDLE 使用位置和高度

Chrome 可以快速处理 100K 行,很难看到显着的性能改进,而对于 Firefox,我必须将行数减少到 10K,性能提升更加明显。