Domanda

Ho questa brutta sensazione su come inserire grandi quantità di HTML.Supponiamo che abbiamo ottenuto:

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

e voglio mettere questo in

$("#mydiv")

in precedenza ho fatto qualcosa di simile

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

È corretto che jQuery è l'analisi di html per creare DOM-Oggetti ?Beh, questo è quello che ho letto da qualche parte (AGGIORNAMENTO: Volevo dire che ho letto, jQuery analizza il codice html per creare l'intera struttura DOM a mano, con le sue sciocchezze, no?!), così ho cambiato il mio codice:

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

Si sente più veloce, vero ?Ed è corretto che questo è equivalente a:

document.getElementById("mydiv").innerHTML += html ?o è jquery fare qualche ulteriore costoso roba in background ?

Mi piacerebbe imparare alternative.

È stato utile?

Soluzione

innerHTML è straordinariamente veloce, e in molti casi otterrai i migliori risultati semplicemente impostandolo (userei solo append).

Tuttavia, se ce n'è già molto in " mydiv " quindi stai forzando il browser ad analizzare e renderizzare di nuovo tutto quel contenuto (tutto quello che c'era prima, più tutto il tuo nuovo contenuto). Puoi evitarlo aggiungendo un frammento di documento su " mydiv " invece:

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

In questo modo, solo il tuo nuovo contenuto viene analizzato (inevitabile) e il contenuto esistente no.

EDIT: Mio cattivo ... Ho scoperto che innerHTML non è ben supportato sui frammenti di documenti. Puoi usare la stessa tecnica con qualsiasi tipo di nodo. Per il tuo esempio, puoi creare il nodo della tabella radice e inserire innerHTML in quello:

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

Altri suggerimenti

Prova quanto segue:

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

Le altre risposte, compresa la risposta accettata, sono più lente di 2-10x : jsperf .

La risposta accettata non funziona in IE 6, 7 e 8 perché non è possibile impostare innerHTML di un elemento <table>, a causa di un bug in IE: jsbin .

Cosa stai cercando di evitare?"Una brutta sensazione" è incredibilmente vago.Se avete sentito il "DOM" è lento" e ha deciso di evitare l'DOM", allora questo è impossibile.Ogni metodo di inserimento di codice in una pagina, tra cui innerHTML, comporterà DOM oggetti che vengono creati.Il DOM è la rappresentazione del documento in memoria del browser.Si vuoi DOM oggetti da creare.

Il motivo per cui la gente dice "DOM è lento" è perché la creazione di elementi con document.createElement(), che è ufficiale DOM interfaccia per la creazione di elementi, è più lento rispetto alle non-standard di proprietà innerHTML in alcuni browser.Questo non significa che la creazione di oggetti DOM è cattivo, è necessario per creare oggetti DOM, altrimenti il codice non fare nulla.

La risposta sull'uso di un frammento DOM è sulla buona strada. Se hai un sacco di oggetti html che stai costantemente inserendo nel DOM, vedrai alcuni miglioramenti della velocità usando il frammento. Questo post di John Resig lo spiega abbastanza bene: http://ejohn.org/blog/dom-documentfragments/

Il modo più veloce per aggiungere elementi

Il modo più veloce per aggiungere all'albero DOM è di bufferizzare tutta la tua aggiunta in un singolo frammento DOM, quindi aggiungere il frammento dom al dom.

Questo è il metodo che uso nel mio motore di gioco.

//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 questo oggetto sono in grado di eseguire il rendering di ~ 1000 elementi sullo schermo ~ 40 volte al secondo in Firefox 4.

Ecco un caso d'uso.

Per cominciare, scrivi uno script che indica il tempo necessario per farlo 100 o 1.000 volte con ciascun metodo.

Per assicurarti che le ripetizioni non siano in qualche modo ottimizzate - non sono un esperto di motori JavaScript - varia l'html che inserisci ogni volta, ad esempio inserendo '0001' quindi '0002' quindi '0003' in una determinata cella della tabella.

Creo una stringa gigante con e quindi aggiungo questa stringa con jquery. Funziona bene e velocemente, per me.

Hai detto di essere interessato alle alternative. Se guardi l'elenco di Plugin jQuery relativi al DOM troverai molti sono dedicati alla generazione programmata di alberi DOM. Vedi ad esempio SuperFlyDom o DOM Elements Creator ; ma ce ne sono altri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top