Griglia dati JavaScript per milioni di righe [chiuso]


225

Devo presentare un gran numero di righe di dati (ad es. Milioni di righe) all'utente in una griglia utilizzando JavaScript.

L'utente non dovrebbe vedere pagine o visualizzare solo quantità finite di dati alla volta.

Piuttosto, dovrebbe sembrare che tutti i dati siano disponibili.

Invece di scaricare i dati tutti in una volta, i piccoli pezzi vengono scaricati man mano che l'utente arriva a loro (cioè scorrendo la griglia).

Le righe non verranno modificate attraverso questo front-end, quindi le griglie di sola lettura sono accettabili.

Quali griglie di dati, scritte in JavaScript, esistono per questo tipo di paging continuo?


1
Non ho accettato la risposta di jqgrid, poiché sembra fallire per grandi set di dati ... Qualche altro suggerimento? Che dire di ext-livegrid.com ?
Rudiger

6
Scrivi il tuo. Sono sicuro che gli altri si stanno soffocando perché continuano ad aggiungere al DOM. Credo che avrete bisogno di una soluzione che rimuove i file come scorrere fuori lo schermo. Questo è l'unico modo. Semplicemente non puoi avere un milione di righe di tabella nel DOM e aspettarti che tutti i browser vengano visualizzati e scorrano senza problemi in ogni ambiente. Essere ragionevole.
Josh Stodola,

2
@Rudiger: SlickGrid ora supporta un numero illimitato di righe in modo nativo. Vedi github.com/mleibman/SlickGrid/tree/unlimited-rows . Una volta che questo viene testato a fondo, verrà unito al ramo principale.
Tin,

10
E mi dispiace per quale impresa tu stia sempre lavorando. Per tua informazione, uno schermo 1920x1080 con solo 1 milione di righe visualizzate salterà 20 righe per ogni pixel di movimento sulla barra di scorrimento. Fai alcuni test di usabilità invece di perdere tempo.
Sleeper Smith,

2
Questa domanda e le sue prime due risposte (almeno) sono estremamente utili. Potrebbe aver attirato alcune risposte di bassa qualità, ma questa domanda non dovrebbe assolutamente essere chiusa. L'uso di SlickGrid per risolvere questo problema può far risparmiare alle persone molte ore di problemi e codici difficili, se tentano di reimplementarlo da soli.
Sam Watkins,

Risposte:


190

( Dichiarazione di non responsabilità: sono l'autore di SlickGrid )

AGGIORNAMENTO Questo è stato ora implementato in SlickGrid .

Si prega di consultare http://github.com/mleibman/SlickGrid/issues#issue/22 per una discussione in corso su come far funzionare SlickGrid con un numero maggiore di righe.

Il problema è che SlickGrid non virtualizza la barra di scorrimento stessa: l'altezza dell'area scorrevole è impostata sull'altezza totale di tutte le righe. Le righe vengono ancora aggiunte e rimosse mentre l'utente scorre, ma lo scorrimento stesso viene eseguito dal browser. Ciò gli consente di essere molto veloce ma fluido (gli eventi onscroll sono notoriamente lenti). L'avvertenza è che ci sono bug / limiti nei motori CSS del browser che limitano l'altezza potenziale di un elemento. Per IE, sembra che sia 0x123456 o 1193046 pixel. Per altri browser è più alto.

Esiste una soluzione sperimentale nel ramo "largenum-fix" che aumenta significativamente tale limite popolando l'area scorrevole con "pagine" impostate su 1 M di altezza pixel e quindi utilizzando il posizionamento relativo all'interno di tali pagine. Poiché il limite di altezza nel motore CSS sembra essere diverso e significativamente inferiore rispetto al motore di layout effettivo, questo ci dà un limite superiore molto più alto.

Sto ancora cercando un modo per raggiungere un numero illimitato di righe senza rinunciare al vantaggio prestazionale che SlickGrid attualmente detiene su altre implementazioni.

Rudiger, puoi approfondire come l'hai risolto?


1
Ho trovato SlickGrid il più interessante, specialmente se si lavora con jQuery. Congratulazioni! (specialmente per l'atteggiamento e la perseveranza grandiosi) :-)
Andras Vass,

Sto cercando di usare slickgrid per mostrare le intestazioni di Excel, e vedo che quando hanno troppe colonne slickgrid ottimizza solo lo scorrimento delle righe e non delle colonne. Ho anche notato che quando si hanno più di 120 colonne o giù di lì, slickgrid inserisce le nuove righe in una nuova riga. È possibile impostare il numero massimo di righe da qualche parte nei file?
Oneiros,

1
SlickGrid v2.1 utilizza lo scorrimento virtuale per colonne e righe. Inoltre, il problema delle colonne straripanti è stato risolto.
Tin,

@Tin - Questo è simile al mio approccio; Ero in anticipo di anni! "Una primitiva di layout a blocchi pigri per la creazione di scroll infiniti in applicazioni Web." docs.google.com/document/d/…
Rudiger,

@Rudiger Sì, l'ho visto sul gruppo Blink circa un mese fa, ma non sono sicuro di come si adatta alla foto. Il layout pigro opera su elementi effettivamente presenti nel DOM, cosa che non possiamo davvero fare. Si prega di elaborare :)
Tin,

84

https://github.com/mleibman/SlickGrid/wiki

" SlickGrid utilizza il rendering virtuale per consentire di lavorare facilmente con centinaia di migliaia di elementi senza alcun calo delle prestazioni. In realtà, non vi è alcuna differenza nelle prestazioni tra lavorare con una griglia con 10 righe rispetto a 100.000 righe. "

Alcuni punti salienti:

  • Scorrimento virtuale adattivo (gestire centinaia di migliaia di righe)
  • Velocità di rendering estremamente elevata
  • Post-rendering in background per celle più ricche
  • Configurabile e personalizzabile
  • Navigazione completa della tastiera
  • Ridimensionamento colonna / riordina / mostra / nascondi
  • Colonna autosizing e force-fit
  • Formatter e editor di celle collegabili
  • Supporto per la modifica e la creazione di nuove righe. "di mleibman

È gratuito (licenza MIT). Usa jQuery.


Funziona bene fino a precisamente 131.001 righe ... Cioè, c'è una riga di codice come questa: data.length = Math.min(131000, parseInt(resp.total));... E, naturalmente, quella codificata per un motivo :(
Rudiger

6
Ci è voluto un po 'di lavoro, ma ho apportato alcune modifiche per rendere la griglia indipendente dalla lunghezza datadell'array. È un kludge, ma ho le risposte che popolano un bigdataarray e i datapull più piccoli bigdatadall'array. Il resto del programma utilizza un array di dati più piccolo, ad eccezione della misurazione della barra di scorrimento e di alcuni altri punti che ora sono illimitati per un gran numero di righe. Tutto sommato, è stato molto più facile che scrivere il mio.
Rudiger,

8
@Rudiger: SlickGrid ora supporta un numero illimitato di righe in modo nativo. Vedi github.com/mleibman/SlickGrid/tree/unlimited-rows . Una volta che questo viene testato a fondo, verrà unito al ramo principale.
Tin,

Sto cercando di usare slickgrid per mostrare le intestazioni di Excel, e vedo che quando hanno troppe colonne slickgrid ottimizza solo lo scorrimento delle righe e non delle colonne. Ho anche notato che quando si hanno più di 120 colonne o giù di lì, slickgrid inserisce le nuove righe in una nuova riga. È possibile impostare il numero massimo di righe da qualche parte nei file?
Oneiros,

se vuoi qualcosa di veramente veloce, non fare affidamento su nulla che usi jquery per fare cose nel core, e piuttosto usi innerHTML piuttosto che l'append DOM. Le barre di scorrimento JavaScript possono essere notevolmente più lente delle barre di scorrimento del browser su computer lenti, evitare regole CSS complesse e si dovrebbe impiegare del tempo a semplificare il layout di una singola riga. Le microottimizzazioni potrebbero essere significative in questo caso. Queste sono solo pratiche generali per migliorare le prestazioni. jsPerf.com è tuo amico.
Vitim.us,

37

Le migliori griglie secondo me sono di seguito:

Le mie 3 migliori opzioni sono jqGrid, jqxGrid e DataTables. Possono lavorare con migliaia di righe e supportare la virtualizzazione.


1
+1 per l'elenco, anche se non c'è molto in termini di confronto. Un buon inizio sarebbe quello di aggiungere il numero di commit per ciascuno - 33 per Flexigrid a partire da ora, contro 491 per SlickGrid.
Dan Dascalescu

12
Avvita il limite di modifica dei commenti di 5 minuti di SO. # 1 - jqGrid - 1000+ commit ; # 2 - 752 per DataTables ; # 3 - 491 per SlickGrid ; # 4 - 33 si impegna per Flexigrid . Ingrid - nessun aggiornamento da giugno 2011 . jqGridView - nessun aggiornamento dal 2009
Dan Dascalescu

3
Sulla base del commento precedente, includo qui il numero di forchette per progetto: # 1 - SlickGrid - 670 forchette; # 2 - jqGrid - 358 forchette; # 3 - Flexigrid - 238; # 4 - DataTables - 216; # 5 - Ingrid - 41; # 6 - jqGridView - 0;
ljs.dev,

1
Dai un'occhiata a nexts.github.io/Clusterize.js
Denis

Posso commentare che Slickgrid è ancora vivo e vegeto, ma il repo mleibman sopra citato è morto. Nuovo link: github.com/6pac/SlickGrid (mleibman lo fa riferimento in una nota finale sul suo repository), o www.slickgrid.net
Ben McIntyre,

25

Non intendo iniziare una guerra alla fiamma, ma supponendo che i tuoi ricercatori siano umani, non li conosci bene come pensi. Solo perché hanno petabyte di dati non li rende in grado di visualizzare anche milioni di record in modo significativo. Potrebbero dire di voler vedere milioni di dischi, ma è solo sciocco. Chiedi ai tuoi ricercatori più intelligenti di fare alcuni calcoli di base: supponi che trascorrano 1 secondo a visualizzare ciascun record. A quel ritmo, ci vorranno 1000000 secondi, che dura più di sei settimane (di 40 ore di lavoro settimanali senza interruzioni per cibo o servizi igienici).

Pensano (o tu) seriamente che una persona (quella che guarda la griglia) possa raccogliere quel tipo di concentrazione? Stanno davvero facendo molto in quel 1 secondo o (più probabilmente) filtrano le cose che non vogliono? Sospetto che dopo aver visualizzato un sottoinsieme di "dimensioni ragionevoli", potrebbero descriverti un filtro che filtrerebbe automaticamente quei record.

Come implicano anche paxdiablo e Sleeper Smith e Lasse V Karlsen, voi (e loro) non avete riflettuto sui requisiti. Sul lato positivo, ora che hai trovato SlickGrid, sono sicuro che la necessità di quei filtri è diventata immediatamente ovvia.


2
Avere la necessità di milioni di righe non significa sempre visualizzarle. A volte i clienti desiderano un dump parziale di record per l'esecuzione nei propri sistemi di analisi dei dati.
cbmeeks,

10
Se si tratta di un dump di dati per la propria analisi, non verrebbe visualizzato in una griglia su una pagina Web, vero?
Steven Benitez,

5
non devo vederli tutti in una volta. Ecco a cosa Ctrl+Fservono l' ordinamento delle colonne . L'alternativa (paging, ricerca di siti Web) è molto peggio. Basta guardare StackOverflow quando si tenta di scorrere domande o risposte, Reddit per scorrere la cronologia dei commenti di un utente. L'ordinamento e la ricerca istantanea forniscono un potere che ha Windows Explorer, ma mancano i siti web.
Ian Boyd,

15

Posso affermare con certezza che non è necessario mostrare all'utente milioni di file di dati.

Non esiste nessun utente al mondo in grado di comprendere o gestire quel set di dati, quindi anche se tecnicamente riuscirai a risolverlo, non risolverai alcun problema noto per quell'utente.

Invece mi concentrerei sul perché l'utente vuole vedere i dati. L'utente non vuole vedere i dati solo per vedere i dati, di solito c'è una domanda che viene posta. Se invece ti concentri sulla risposta a queste domande, allora saresti molto più vicino a qualcosa che risolve un problema reale.


16
I miei utenti sono ricercatori che sono abituati a petabyte di dati. Penso di conoscere i miei utenti un po 'meglio di te, anche se hai certamente ragione nel caso generale. Per quanto riguarda il perché , questo datagrid fa semplicemente parte di una serie di strumenti per la gestione dei big data.
Rudiger,

7

Consiglio Ext JS Grid con la funzione Buffered View.

http://www.extjs.com/deploy/dev/examples/grid/buffer.html


ExtJs, davvero. Fondamentalmente è costruito appositamente per la presentazione dei dati
KdgDev,

1
ExtJs è così bello che voglio piangere che non è costruito su jQuery
James Westgate,

Ora puoi caricare solo le parti relative alla griglia di ExtJS, in modo che l'aggiunta di una griglia ExtJS alla tua applicazione non sia troppo pesante. Tuttavia, devi ancora considerare le differenze di aspetto e utilizzare il modo di tematizzare ExtJS solo per quel componente.
JD Smith,

7

(Dichiarazione di non responsabilità: sono l'autore di w2ui)

Di recente ho scritto un articolo su come implementare la griglia JavaScript con 1 milione di record ( http://w2ui.com/web/blog/7/JavaScript-Grid-with-One-Million-Records ). Ho scoperto che alla fine ci sono 3 restrizioni che impediscono di prenderlo più in alto:

  1. L'altezza del div ha un limite (può essere superata mediante scorrimento virtuale)
  2. Operazioni come l'ordinamento e la ricerca iniziano a essere lente dopo circa 1 milione di record
  3. La RAM è limitata perché i dati sono memorizzati nell'array JavaScript

Ho testato la griglia con 1 milione di record (tranne IE) e funziona bene. Vedi l'articolo per demo ed esempi.


Con questo milione di record la tua pagina html ha dimensioni di 3 MB, ma quando carico i miei dati la pagina è di 15 MB, w2ui è in grado di gestirlo? Ho bisogno di tutti i dati per alcuni calcoli.
Chetan S. Choudhary,

6

dojox.grid.DataGrid offre un'astrazione JS per i dati in modo che tu possa collegarlo a vari back-end con negozi dojo.data forniti o scrivere il tuo. Avrai ovviamente bisogno di uno che supporti l'accesso casuale per così tanti record. DataGrid offre anche piena accessibilità.

Modifica quindi ecco un link all'articolo di Matthew Russell che dovrebbe fornire l'esempio di cui hai bisogno, visualizzando milioni di record con dojox.grid. Si noti che utilizza la vecchia versione della griglia, ma i concetti sono gli stessi, c'erano solo alcuni miglioramenti API incompatibili.

Oh, ed è totalmente open source gratuito.



4

Ecco un paio di ottimizzazioni che puoi applicare per accelerare le cose. Sto solo pensando ad alta voce.

Poiché il numero di righe può essere in milioni, è necessario un sistema di memorizzazione nella cache solo per i dati JSON dal server. Non riesco a immaginare nessuno che voglia scaricare tutti gli X milioni di articoli, ma se lo facessero, sarebbe un problema. Questo piccolo test su Chrome per un array su 20M + numeri interi si blocca costantemente sulla mia macchina.

var data = [];
for(var i = 0; i < 20000000; i++) {
    data.push(i);
}
console.log(data.length);​

È possibile utilizzare LRU o qualche altro algoritmo di memorizzazione nella cache e avere un limite superiore alla quantità di dati che si desidera memorizzare nella cache.

Per le stesse celle di tabella, penso che costruire / distruggere nodi DOM possa essere costoso. Invece, potresti semplicemente pre-definire il numero X di celle e ogni volta che l'utente scorre in una nuova posizione, iniettare i dati JSON in queste celle. La barra di scorrimento non avrebbe praticamente alcuna relazione diretta con la quantità di spazio (altezza) necessaria per rappresentare l'intero set di dati. È possibile impostare arbitrariamente l'altezza del contenitore della tabella, ad esempio 5000px, e mapparla sul numero totale di righe. Ad esempio, se l'altezza contenitori è 5000px e ci sono un totale di righe 10M, quindi il starting row ≈ (scroll.top/5000) * 10Mquale scroll.toprappresenta la distanza di scorrimento dalla parte superiore del contenitore. Piccola demo qui .

Per rilevare quando richiedere più dati, idealmente un oggetto dovrebbe fungere da mediatore che ascolta gli eventi di scorrimento. Questo oggetto tiene traccia della velocità con cui l'utente scorre, e quando sembra che l'utente stia rallentando o si sia completamente arrestato, effettua una richiesta di dati per le righe corrispondenti. Recuperare i dati in questo modo significa che i tuoi dati saranno frammentati, quindi la cache dovrebbe essere progettata tenendo presente questo aspetto.

Anche i limiti del browser per le connessioni in uscita massime possono svolgere un ruolo importante. Un utente può scorrere fino a una determinata posizione che genererà una richiesta AJAX, ma prima che ciò finisca l'utente può scorrere fino a qualche altra porzione. Se il server non è abbastanza reattivo, le richieste verrebbero messe in coda e l'applicazione non risponderà. È possibile utilizzare un gestore richieste attraverso il quale vengono instradate tutte le richieste e può annullare le richieste in sospeso per fare spazio.


4

So che è una vecchia domanda, ma comunque ... C'è anche dhtmlxGrid che può gestire milioni di righe. Esiste una demo con 50.000 righe ma il numero di righe che è possibile caricare / elaborare nella griglia è illimitato.

Disclaimer: vengo dal team DHTMLX.


Voglio mostrare i dati Json da 10 MB e voglio usarli nel calcolo, DHTMLX può fare quella cosa, con quei dati e tag html la pagina del mio browser è di circa 15 MB. Vale la pena usare DHTMLX?
Chetan S. Choudhary,


3

Disclaimer: io pesantemente uso YUI DataTable senza alcun mal di testa per un lungo periodo di tempo . È potente e stabile. Per le tue esigenze, puoi utilizzare una tabella ScrollingData che supporta

  • x-scrolling
  • y-scorrimento
  • xy-scrolling
  • Un potente meccanismo di eventi

Per quello che ti serve, penso che tu voglia sia un tableScrollEvent . La sua API dice

Attivato quando una DataTable a scorrimento fisso ha uno scorrimento.

Poiché ogni DataTable utilizza una DataSource, è possibile monitorare i suoi dati tramite tableScrollEvent insieme alle dimensioni del loop di rendering al fine di popolare la ScrollingDataTable in base alle proprie esigenze.

Indica la dimensione del loop di rendering

Nei casi in cui DataTable deve visualizzare l'insieme di un set di dati molto ampio, la configurazione renderLoopSize può aiutare a gestire il rendering DOM del browser in modo che il thread dell'interfaccia utente non venga bloccato su tabelle molto grandi . Qualsiasi valore maggiore di 0 farà eseguire il rendering DOM in catene setTimeout () che eseguono il rendering del numero specificato di righe in ciascun ciclo. Il valore ideale dovrebbe essere determinato per implementazione poiché non esistono regole rigide e veloci, ma solo linee guida generali:

  • Per impostazione predefinita, renderLoopSize è 0, quindi tutte le righe sono visualizzate in un singolo ciclo. Un renderLoopSize> 0 aggiunge un sovraccarico, quindi usalo attentamente.
  • Se il tuo set di dati è abbastanza grande (numero di righe X numero di complessità di formattazione Colonne X) che gli utenti sperimentano la latenza nel rendering visivo e / o causa il blocco dello script, considera l'impostazione di renderLoopSize .
  • Un renderLoopSize sotto 50 probabilmente non ne vale la pena. Un renderLoopSize> 100 è probabilmente migliore.
  • Un set di dati probabilmente non è considerato abbastanza grande a meno che non abbia centinaia e centinaia di righe.
  • Avere renderLoopSize> 0 e <righe totali fa sì che la tabella sia renderizzata in un ciclo (uguale a renderLoopSize = 0) ma innesca anche funzionalità come lo striping di righe post-rendering da gestire da un thread setTimeout separato.

Per esempio

// Render 100 rows per loop
 var dt = new YAHOO.widget.DataTable(<WHICH_DIV_WILL_STORE_YOUR_DATATABLE>, <HOW YOUR_TABLE_IS STRUCTURED>, <WHERE_DOES_THE_DATA_COME_FROM>, {
     renderLoopSize:100
 });

<WHERE_DOES_THE_DATA_COME_FROM> è solo una singola origine dati . Può essere un JSON, JSFunction, XML e persino un singolo elemento HTML

Qui puoi vedere un semplice tutorial, fornito da me. Essere consapevoli senza altri supporti DATA_TABLE pluglin singolo e doppio click allo stesso tempo. YUI DataTable ti consente. Inoltre, puoi usarlo anche con JQuery senza mal di testa

Alcuni esempi, puoi vedere

Sentiti libero di fare domande su tutto ciò che desideri su YUI DataTable.

Saluti,


3

Non riesco a vedere il punto, per jqGrid puoi usare la funzionalità di scorrimento virtuale:

http://www.trirand.net/aspnetmvc/grid/performancevirtualscrolling

ma poi di nuovo, è possibile eseguire milioni di righe con filtro:

http://www.trirand.net/aspnetmvc/grid/performancelinq

Non riesco davvero a vedere il punto di "come se non ci fossero pagine" però, intendo ... non c'è modo di visualizzare 1.000.000 di righe contemporaneamente nel browser - si tratta di 10 MB di HTML grezzo, non riesco a vedere perché gli utenti non vorrebbero vedere le pagine.

Comunque...


2

il miglior approccio che mi viene in mente è quello di caricare il blocco di dati in formato json per ogni scorrimento o qualche limite prima che lo scorrimento termini. json può essere facilmente convertito in oggetti e quindi le righe della tabella possono essere costruite facilmente in modo discreto


Ecco come ce l'ho. Viene fatta una richiesta per un set di righe rinviate in JSON ... Sto cercando un renderer lato client javascript che supporti questo!
Rudiger

Che cosa??? Che diamine è "renderizzatore del sito client"? Qualsiasi javascript dovrà comunque effettuare una chiamata ajax, quindi dovrai comunque scegliere un formato di trasporto. Non puoi scappare facendo un po 'di lavoro. Nessuno lo farà per te amico mio.
Andriy Drozdyuk,

1
So che è necessario effettuare una chiamata AJAX; questa parte è semplice. Il client richiede qualcosa come "start = 20 & limit = 20" e recupera le righe 20-39 dal server (formato XML o JSON). Il "renderizzatore lato client" (la mia terminologia!) Fa queste richieste in modo intelligente (ad es. Quando l'utente scorre verso il basso) e rende i risultati senza soluzione di continuità in una griglia carina. Contrariamente a quello che dici, qualcun altro ha fatto questo lavoro per me. Ecco cosa sono tutte le altre risposte a questa domanda.
Rudiger,

Bene, sembra che nessun "altro" l'abbia fatto per te :)
Andriy Drozdyuk,

1

Consiglio vivamente Open rico . È difficile da implementare all'inizio, ma una volta che lo afferrerai non tornerai mai indietro.




0

Dai un'occhiata a dGrid:

https://dgrid.io/

Concordo sul fatto che gli utenti non dovranno MAI, MAI visualizzare milioni di righe di dati contemporaneamente, ma dGrid può visualizzarle rapidamente (uno schermo alla volta).

Non far bollire l'oceano per fare una tazza di tè.


la tua tazza di tè (link) non è stata trovata. :)
Akshay,

Ora ha il suo sito :)
ColemanTO
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.