interactuando rápidamente con una gran cantidad de elementos dentro de un contenedor (DOM, javascript)

Así que tengo una gran cantidad de divs (4000-5000) [cada uno contiene tramos, anclas, imágenes, etc.] dentro de un contenedor div y, básicamente, estoy configurando su pantalla como none o block en función de una condición. Esto toma algo de tiempo.

En mi búsqueda de algo más rápido, encontré esta página https://developers.google.com/speed/articles/javascriptdom y la solución es eliminar el contenedor div del DOM e iterar los elementos contenidos por 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(); } 

El problema es que no puedo usar la solución provista porque necesito acceder a los elementos secundarios por sus IDs y no puedo hacer eso, ya que los elementos se eliminan del DOM. ¿Hay alguna forma de lograr esto?

También traté de eliminar el contenedor div y anexarlo a un documentfragment, pero aún así no puedo acceder a los 5000 elementos por su ID cuando están en el documentfragment

Finalmente, también intenté esto:

 document.getElementById("CONTAINERDIV").style.display = "none"; //iterate through the 5000 children divs and change their classname document.getElementById("CONTAINERDIV").style.display = "block"; 

porque esperaba que no provocara un reflujo para cada iteración, pero esto no pareció proporcionar una mejora en el tiempo requerido.

¿Alguien tiene alguna idea sobre esto?

Mostrar ninguno / bloquear es costoso. Desde mis días de mejorar el rendimiento en las plataformas web de negociación, una técnica que puedo recomendar que brillará especialmente con los navegadores más antiguos es usar el relativo a la posición y sacarlo de la pantalla con un valor negativo a la izquierda. Por supuesto, dependiendo de su implementación, es posible que desee establecer la altura en 0px también o buscar posibilidades con la posición absoluta. El concepto central sigue siendo que simplemente está tirando del elemento de la pantalla. La buena noticia es que los elementos ocultos todavía están en el DOM y puede acceder a ellos.

 div { position: relative; left: 0px; } div.hide { left: -4096px; height: 0px; } 

Echa un vistazo a estos dos violines, crean 10K filas y alternan (esconden / muestran) las filas impares:

FIDDLE usando Display none / block

FIDDLE usando posición y altura

Chrome maneja 100K de estas filas en un abrir y cerrar de ojos y es difícil ver una mejora significativa en el rendimiento, mientras que para Firefox tuve que reducir el conteo de filas a 10K y la ganancia de rendimiento es mucho más evidente.

Trataré de proporcionar las fonts según lo solicitado.

Primera solución – la mejor
De acuerdo con este sitio: JavaScript Grid con One Million Records
Puedes aprender varias cosas importantes:

  1. Un gran número de nodos DOM hace que la renderización sea lenta
  2. Las matrices de JavaScript pueden manejar grandes conjuntos de datos
  3. Looping a través de grandes arreglos es rápido
  4. La ordenación de matrices al proporcionar funciones personalizadas para Array.sort () es rápida
  5. eval () es lento, no debe usarse en bucles grandes

Por lo tanto, le recomendaría que construya una matriz para manejar de manera rápida sus elementos.

Segunda solución
Otra solución tomada de este sitio: procesamiento de grandes cantidades de datos en JavaScript
sería usar un tiempo de espera (tan extraño como suena) para boost la velocidad del controlador.
La idea proviene de Book: Secrets of the JavaScript Ninja

Si solo quieres mostrar / ocultar, sin cambiar nada en el DOM del div y conoces todos los ID, creo que la mejor forma (la más rápida) de archivar esto sería preparar el elemento

y anexarlo a DOM . Style el debe contener todas las identificaciones y la visualización adecuada. Itere a través de los ID y agréguelos a la cadena CSS, luego cree el elemento

y agregue una cadena a él. Esto debería funcionar para ti.

Cree una tabla de mapa / hash de id-to-element de antemano:

 var map = {}; for (var i = 0, l = ids.length; i < l; i++) { map[ids[i]] = document.getElementById(ids[i]); } 

donde ids es una lista de ID de elementos. (Si necesita 5000 elementos por sus identificaciones, supongo que tiene una lista o puede generar una).

Luego, cuando elimina el elemento del contenedor del DOM, puede usar el mapa para buscar elementos por sus ID.

Las siguientes dos declaraciones son equivalentes (el segundo enfoque requiere el # pero está disponible en todos los elementos, no solo en el documento).

 elt = document.getElementById("theId"); elt = document.querySelector("#theId"); 

De modo que puede usar element.querySelector('#theId') para llegar a un elemento secundario en función de su ID (incluso si el element principal está actualmente separado de DOM).

Tenga en cuenta que querySelector () no es compatible con IE 7 y versiones anteriores.

Si quiere ocultar o mostrar todos los elementos, ¿por qué no dejar que css lo haga por usted?

http://jsfiddle.net/M3gye/

HTML:

  
div1
div2
div3
div4
div5
div6
div7
div8
div9

CSS:

 .border { border: 1px solid black; background-color: lightblue; } .hide div { display: none; } 

JAVASCRIPT:

 function toggle_divs() { var d = document.getElementById('container1'); if (d) { if (d.className == "hide") d.className = ""; else d.className = "hide"; } } 

En este ejemplo, todo lo que hago es establecer la clase del contenedor div y dejar los selectores al rest para mí.