Creazione dynamic di grandi tabelle html in prestazioni javascript

Ho un’applicazione che viene utilizzata per l’analisi dei dati e sto riscontrando alcuni problemi di prestazioni con la creazione della tabella. I dati vengono estratti dai documenti ed è importante che tutti i dati siano presentati su una pagina (purtroppo l’impaginazione non è un’opzione).

Usando jQuery, faccio una richiesta Ajax al server per recuperare i dati. Al completamento della richiesta, trasferisco i dati a una funzione di output. La funzione di output scorre attraverso l’array di dati utilizzando un ciclo for e concatenando le righe a una variabile. Una volta completato il ciclo, la variabile che contiene la tabella viene quindi aggiunta a un div esistente nella pagina e quindi vado a associare gli eventi alla tabella per lavorare con i dati.

Con un piccolo insieme di dati (~ 1000-2000 righe) funziona in modo relativamente soddisfacente, ma alcuni set di dati contengono fino a 10.000 righe che causano l’arresto o la chiusura di Firefox o la mancata risposta.

La mia domanda è, c’è un modo migliore per realizzare ciò che sto facendo?

Ecco un codice:

//This function gets called by the interface with an id to retrieve a document function loadDocument(id){ $.ajax({ method: "get", url: "ajax.php", data: {action:'loadDocument',id: id}, dataType: 'json', cache: true, beforeSend: function(){ if($("#loading").dialog('isOpen') != true){ //Display the loading dialog $("#loading").dialog({ modal: true }); }//end if },//end beforesend success: function(result){ if(result.Error == undefined){ outputDocument(result, id); }else{  }//end if if($('#loading').dialog('isOpen') == true){ //Close the loading dialog $("#loading").dialog('close'); }//end if }//end success });//end ajax };//end loadDocument(); //Output document to screen function outputDocument(data, doc_id){ //Begin document output var rows = ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; for(var i in data){ var recordId = data[i].id; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += ''; }//end for rows += ''; rows += '
IDStatusNameActionsOrigin
' + recordId + '' + data[i].status + '' + data[i].name + ''; rows += ''; rows += ''; rows += '' + data[i].origin + '
'; $('#documentRows').html(rows);

Inizialmente, stavo usando un jQuery ogni ciclo, ma passai al ciclo for che cancellò alcuni ms.

Ho pensato di utilizzare qualcosa come google gears per provare a scaricare alcune delle elaborazioni (se ansible in questo scenario).

qualche idea?

joinHi,

Il rendering è un problema, ma c’è anche un problema nel concatenare così tante stringhe all’interno del ciclo, specialmente quando la stringa diventa molto grande. Sarebbe probabilmente meglio mettere le stringhe in singoli elementi di un array e infine usare “join” per creare l’enorme stringa in un colpo solo. per esempio

 var r = new Array(); var j = -1, recordId; r[++j] = ''; for (var i in data){ var d = data[i]; recordId = d.id; r[++j] = ''; } r[++j] = '
IDStatusNameActionsOrigin
'; r[++j] = recordId; r[++j] = ''; r[++j] = d.status; r[++j] = ''; r[++j] = d.name; r[++j] = ''; r[++j] = d.origin; r[++j] = '
'; $('#documentRows').html(r.join(''));

Inoltre, vorrei utilizzare il metodo di indicizzazione degli array mostrato qui, piuttosto che usare “push” poiché, per tutti i browser ad eccezione di Google Chrome, è più veloce, secondo questo articolo .

La visualizzazione di molte righe sta causando il rallentamento del motore di rendering del browser, non il motore JavaScript. Sfortunatamente non c’è molto che tu possa fare al riguardo.

La soluzione migliore è semplicemente non visualizzare così tante righe contemporaneamente, sia attraverso l’impaginazione che lo scorrimento virtuale.

Il modo in cui stai costruendo la stringa causerà enormi quantità di garbage collection.

Man mano che la stringa diventa sempre più lunga, il motore javascript deve continuare a allocare buffer più grandi e scartare quelli vecchi. Alla fine non sarà in grado di allocare memoria sufficiente senza riciclare i resti di tutte le vecchie stringhe.

Questo problema peggiora man mano che la stringa cresce più a lungo.

Prova invece ad aggiungere nuovi elementi al DOM uno alla volta usando l’ API di manipolazione jQuery

Considerare anche solo il rendering di ciò che è visibile e implementare il proprio scorrimento.

Puoi fare un paio di cose per aumentare le prestazioni:

  1. la tua variabile rows diventa sempre più grande, quindi non salvare l’html in una variabile. la soluzione può essere la funzione $.each() e ogni funzione che si aggiunge all’elemento in DOM. Ma questo è un aggiustamento minore.
  2. Generare HTML è buono, ma puoi provare a creare e aggiungere DOM. Mi piace $('

    ') .

  3. Infine, questo risolverà sicuramente il tuo problema: utilizzare più chiamate ajax nella prima chiamata ajax per raccogliere quanti dati sono disponibili e recuperare circa 1.000 o più dati. E usa altre chiamate per raccogliere i dati rimanenti. Se lo desideri, puoi utilizzare saggiamente le chiamate sincrone o asincrone.

Ma cerca di evitare di memorizzare il valore. La tua dimensione DOM sarà enorme ma dovrebbe funzionare con i browser moder e dimenticare IE6.

@ fuel37: esempio

 function outputDocumentNew(data, doc_id) { //Variable DOM's var rowSample = $('').addClass('row-class'); var colSample = $('').addClass('col-class'); var spanSample = $('').addClass('span-class'); var inputButtonSample = $('').addClass('input-class'); //DOM Container var container = $('#documentRows'); container.empty().append('
'); //Static part var head = '\ \ ID\ Status\ Name\ Actions\ Origin\ \ '; container.append(head); var body = $(''); container.append(body); //Dynamic part $.each(data, function (index, value) { var _this = this; //DOM Manupulation var row = rowSample.clone(); //Actions var inpFailOne = inputButtonSample.clone().val('F').attr('rev', _this.id).addClass('failOne').click(function (e) { //do something when click the button. }); var inpPromoteOne = inputButtonSample.clone().val('P').attr('rev', _this.id).addClass('promoteOne').click(function (e) { //do something when click the button. }); row .append(colSample.clone().append(_this.id)) .append(colSample.clone().append(spanSample.colne().addClass('status').append(_this.status))) .append(colSample.clone().append(spanSample.colne().addClass('name').append(_this.name))) .append(colSample.clone().append(inpFailOne).append(inpPromoteOne)) .append(colSample.clone().append(_this.origin)); body.append(row); }); }

in questo processo è necessario creare e mantenere ID o classi per la manipolazione. Hai il controllo per associare eventi e manipolare ogni elemento lì.

Risposta per ottenere la formattazione

Cosa succede se lo fai

 for(var i in data){ var record = data[i]; var recordId = record.id; rows += ''; rows += '' + recordId + ''; rows += '' + data[i].status + ''; rows += '' + record.name + ''; rows += ''; rows += ''; rows += ''; rows += ''; rows += '' + record.origin + ''; rows += ''; }//end for 

Per altri suggerimenti (non sono abbastanza affidabile da commentare ancora, scusa!), Potresti provare il plug-in TableSorter per gestire solo la visualizzazione di una quantità utilizzabile di dati alla volta.

Non so come valga un numero molto alto di righe, ma i loro dati di esempio sono circa 1000 righe.

Questo non sarebbe d’aiuto con le prestazioni di JS ma manterrebbe il peso del rendering del browser.

Potrebbe provare questo …

Migliora i loop

Migliora String Concat

 var tmpLst = []; for (var i=0, il=data.length; i'); tmpLst.push(''); ...ect... } rows += tmpLst.join(''); 

Questo potrebbe spremere un po ‘di prestazioni in più …

 var lstReset = i * lstReset.length; tmpLst[lstReset + 1]='.toArray (new MyClass ) o .toArray (new MyClass )?
  • INNER JOIN vs LEFT JOIN prestazioni in SQL Server
  • Qual è il modo migliore per tracciare l'esecuzione di javascript?
  • Dimensione di un byte in memoria - Java
  • Che cosa innesca una garbage collection completa in Java?
  • Impostazioni MySQL ottimali per query che forniscono grandi quantità di dati?
  • Prestazioni di JavaFx Gui vs Swing
  • Cos'è più veloce, iterando un vettore STL con vector :: iterator o con a ()?