2010-04-22 10 views
5

Ho una ricerca che restituisce JSON, che poi trasformo in una tabella HTML in Javascript. Chiama ripetutamente il metodo jQuery.append(), una volta per ogni riga. Ho una macchina moderna e il tempo di risposta di Firefox è accettabile. Ma in IE 8 è insopportabilmente lento.Qual è il modo più efficiente per gestire dataset di grandi dimensioni con Javascript/jQuery in IE?

Ho deciso di spostare la trasformazione da dati in HTML nel PHP lato server, cambiando il tipo di ritorno da JSON a HTML. Ora, anziché chiamare ripetutamente il tempo jQuery.append(), chiamo il metodo jQuery.html() una volta con l'intera tabella. Ho notato che Firefox è diventato più veloce, ma IE è diventato più lento.

Questi risultati sono aneddotici e non ho eseguito alcun benchmarking, ma le prestazioni di IE sono molto deludenti. C'è qualcosa che posso fare per accelerare la manipolazione di grandi quantità di dati in IE o è semplicemente una cattiva idea elaborare molti dati contemporaneamente con AJAX/Javascript?

risposta

9

Come altri hanno detto, eccessiva manipolazione del DOM uccide le prestazioni. La creazione di una stringa HTML utilizzando il summenzionato Array.join ('') e l'impostazione di innerHTML di un contenitore utilizzando il metodo jQuery.html() sono gli ordini di grandezza più veloci. Fai attenzione all'utilizzo di jQuery.append (html): equivale a creare prima tutti i nodi DOM e quindi a inserirli!

Il fatto è che, anche se si ottimizza la creazione dell'albero dei nodi di pagina, si arriverà a colpire un soffitto abbastanza velocemente con dataset molto grandi. I browser non sono in grado di gestire alberi DOM così grandi e complessi. La prima cosa che vedrai rallentare saranno le interazioni (animazioni, gestori, ecc.) Anche se usi la delega degli eventi. Se il set di dati è veramente grande, è necessario eseguire una sorta di virtualizzazione per mostrare solo ciò che è visibile nel viewport (questo è ciò che fa SlickGrid - http://github.com/mleibman/slickgrid).

In alternativa, è possibile migliorare la reattività e il "tempo di interazione" della pagina dividendo le aggiunte del DOM ed eseguendole su un timeout uno dopo l'altro, con una pausa intermedia per consentire al browser di gestire gli eventi utente.

Altre tecniche includono il rendering del valore della prima pagina di dati, l'allocazione di spazio per ulteriori informazioni, ma il rendering solo quando l'utente inizia a scorrere verso di esso. Questo è ciò che fa Facebook.

+0

Hai assolutamente ragione. ... ma quanto è veloce "sei nella finestra"? –

+0

Immagino tu intenda il controllo della posizione di scorrimento. Il controllo in sé è piuttosto veloce, specialmente se lo metti su un timeout piccolo. Dai un'occhiata agli esempi SlickGrid: la griglia esegue il rendering di 50.000 righe, tuttavia è estremamente veloce e reattiva. – Tin

+0

Ho appena finito di implementare SlickGrid ed è sorprendente. È senza dubbio il più potente plugin jQuery che abbia mai usato, e mi ha salvato dal dover ridisegnare un grosso pezzo del mio progetto per trattare con IE. Grazie! –

3

L'ho già fatto. È tutta la manipolazione DOM che rallenta le cose a causa del processo di riverniciatura/rifusione che si attiva dopo ogni aggiunta.

Costruirlo come una stringa sul client, inserire la stringa nel DOM utilizzando .html().

Questo ha funzionato abbastanza bene per me, anche su IE6.

+1

È vero: non otterrete grandi prestazioni da IE (<9) con dataset di grandi dimensioni, ma l'impostazione di innerHTML è in genere molto più rapida dell'inserimento di un gruppo di nodi DOM con IE, indipendentemente dal framework JS che potreste stare usando –

1

Più operazioni di aggiunta DOM annullano le prestazioni. E potresti anche incontrare un problema con l'immutabilità delle stringhe.

Mantenere i dati più piccoli possibile (gli array JSON sono buoni) e creare lo html nello script evitando il problema di concatenazione della stringa javascript. Aggiungere i valori html a un array e quindi unirli successivamente all'array. Aggiungi un DOM una volta creato il codice HTML. ad esempio

var builder = []; 

//Inside a loop 
builder.push('<tr><td>'); 
builder.push(json.value); 
builder.push('</tr>'); 

//Outside the loop 
$('div').append(builder.join('')); 
0

Consiglio vivamente il jQuery templating plugin,

Sono stato con funzione di micro-template di John Resig per alcuni mesi. Il plugin di template è l'evoluzione di questo. Ho scritto e la presentazione su di esso tutto l'anno :)

My Blog

Problemi correlati