Pregunta

Tengo un mal presentimiento acerca de cómo inserto grandes cantidades de HTML.Supongamos que tenemos:

var html="<table>..<a-lot-of-other-tags />..</table>"

y quiero poner esto en

$("#mydiv")

anteriormente hice algo como

var html_obj = $(html); $("#mydiv").append(html_obj);

¿Es correcto que jQuery esté analizando? html para crear objetos DOM?Bueno esto es lo que leí en alguna parte. (ACTUALIZAR: Quise decir que he leído, jQuery analiza el html para crear todo el árbol DOM a mano. No tiene sentido, ¿verdad?), así que cambié mi código:

$("#mydiv").attr("innerHTML", $("#mydiv").attr("innerHTML") + html);

Se siente más rápido, ¿verdad?¿Y es correcto que esto sea equivalente a:

document.getElementById("mydiv").innerHTML += html ?¿O jquery está haciendo algunas cosas costosas adicionales en segundo plano?

También me encantaría aprender alternativas.

¿Fue útil?

Solución

InnerHTML es notablemente rápido y, en muchos casos, obtendrá los mejores resultados simplemente configurándolo (yo solo usaría append).

Sin embargo, si ya hay mucho en "mydiv", entonces estás obligando al navegador a analizar y representar todo ese contenido nuevamente (todo lo que estaba allí antes, más todo el contenido nuevo). Puedes evitar esto agregando un fragmento de documento a "mydiv" en su lugar:

var frag = document.createDocumentFragment();
frag.innerHTML = html;
$("#mydiv").append(frag);

De esta manera, solo se analiza el contenido nuevo (inevitable) y el contenido existente no.

EDITAR:Culpa mía...Descubrí que internalHTML no es compatible con fragmentos de documentos.Puede utilizar la misma técnica con cualquier tipo de nodo.Para su ejemplo, podría crear el nodo de la tabla raíz e insertar el HTML interno en él:

var frag = document.createElement('table');
frag.innerHTML = tableInnerHtml;
$("#mydiv").append(frag);

Otros consejos

Pruebe lo siguiente:

$("#mydiv").append(html);

Las otras respuestas, incluida la respuesta aceptada, son Más lento por 2-10x: jsperf.

La respuesta aceptada no funciona en Es decir, 6, 7 y 8 porque no puedes configurar innerHTML de un <table> elemento, debido a un error en IE: jsbin.

¿Qué estás intentando evitar?"Un mal presentimiento" es increíblemente vago.Si escuchó "el DOM es lento" y decidió "evitar el DOM", entonces esto es imposible.Cada método de inserción de código en una página, incluido InnerHTML, dará como resultado la creación de objetos DOM.El DOM es la representación del documento en la memoria de su navegador.Tú desear Objetos DOM que se crearán.

La razón por la que la gente dice "el DOM es lento" es porque crear elementos con document.createElement(), que es la interfaz DOM oficial para crear elementos, es más lento que usar la propiedad internalHTML no estándar en algunos navegadores.Esto no significa que crear objetos DOM sea malo, es necesario para crear objetos DOM; de lo contrario, su código no haría nada en absoluto.

La respuesta sobre el uso de un fragmento DOM va por buen camino.Si tiene un montón de objetos html que inserta constantemente en el DOM, verá algunas mejoras de velocidad al usar el fragmento.Esta publicación de John Resig lo explica bastante bien:http://ejohn.org/blog/dom-documentfragments/

La forma más rápida de agregar elementos

La forma más rápida de agregar al árbol DOM es almacenar todos los archivos adjuntos en un solo fragmento de DOM y luego agregar el fragmento de DOM al dom.

Este es el método que uso en mi motor de juego.

//Returns a new Buffer object
function Buffer() {

    //the framgment
    var domFragment = document.createDocumentFragment();

    //Adds a node to the dom fragment
    function add(node) {
        domFragment.appendChild(node);
    }

    //Flushes the buffer to a node
    function flush(targetNode) {

        //if the target node is not given then use the body
        var targetNode = targetNode || document.body;

        //append the domFragment to the target
        targetNode.appendChild(domFragment);

    }

    //return the buffer
    return {
        "add": add,
        "flush": flush
    }
}


//to make a buffer do this
var buffer = Buffer();

//to add elements to the buffer do the following
buffer.add(someNode1);

//continue to add elements to the buffer
buffer.add(someNode2);
buffer.add(someNode3);
buffer.add(someNode4);
buffer.add(someN...);

//when you are done adding nodes flush the nodes to the containing div in the dom
buffer.flush(myContainerNode);

Usando este objeto puedo representar ~1000 elementos en la pantalla ~40 veces por segundo en Firefox 4.

Aquí hay un caso de uso.

Para empezar, escriba un script que multiplique el tiempo que lleva hacerlo 100 o 1000 veces con cada método.

Para asegurarse de que las repeticiones no estén optimizadas de alguna manera (no soy un experto en motores JavaScript), varíe el html que inserta cada vez, digamos poniendo '0001', luego '0002' y luego '0003' en un determinado celda de la tabla.

Creo una cadena gigante y luego agrego esta cadena con jquery.Funciona bien y rápido para mí.

Mencionas estar interesado en alternativas.Si miras el listado de Complementos jQuery relacionados con DOM Encontrará varios que están dedicados a generar árboles DOM mediante programación.ver por ejemplo SuperFlyDom o Creador de elementos DOM;pero hay otros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top