Grille de données JavaScript pour des millions de lignes [fermé]


225

Je dois présenter un grand nombre de lignes de données (c'est-à-dire des millions de lignes) à l'utilisateur dans une grille en utilisant JavaScript.

L'utilisateur ne doit pas voir les pages ou afficher uniquement des quantités limitées de données à la fois.

Il devrait plutôt apparaître que toutes les données sont disponibles.

Au lieu de télécharger les données en une seule fois, de petits morceaux sont téléchargés au fur et à mesure que l'utilisateur les rencontre (c'est-à-dire en faisant défiler la grille).

Les lignes ne seront pas modifiées via ce frontal, les grilles en lecture seule sont donc acceptables.

Quelles grilles de données, écrites en JavaScript, existent pour ce type de pagination transparente?


1
J'ai refusé la réponse jqgrid, car elle semble échouer pour les grands ensembles de données ... D'autres suggestions? Et ext-livegrid.com ?
Rudiger

6
Écrivez votre propre. Je suis sûr que les autres s'étouffent parce qu'ils continuent de s'ajouter au DOM. Je pense que vous aurez besoin d'une solution qui supprime les lignes lorsqu'elles défilent sur l'écran. C'est la seule façon. Vous ne pouvez tout simplement pas avoir un million de lignes de table dans le DOM et vous attendre à ce que chaque navigateur affiche et défile de manière transparente dans chaque environnement. Être raisonnable.
Josh Stodola

2
@Rudiger: SlickGrid prend désormais en charge un nombre illimité de lignes en mode natif. Voir github.com/mleibman/SlickGrid/tree/unlimited-rows . Une fois que cela sera testé à fond, il sera fusionné dans la branche principale.
Tin

10
Et je suis désolé pour quelle entreprise pour laquelle vous travaillez. Pour votre information, un écran de 1920 x 1080 avec seulement 1 million de lignes affichées sautera de 20 lignes pour chaque pixel de mouvement sur la barre de défilement. Allez faire des tests d'utilisabilité au lieu de perdre votre temps.
Sleeper Smith

2
Cette question et ses deux premières réponses (au moins) sont extrêmement utiles. Cela aurait pu attirer des réponses de mauvaise qualité, mais en aucun cas cette question ne devrait être fermée. L'utilisation de SlickGrid pour résoudre ce problème peut permettre aux utilisateurs d'économiser de nombreuses heures de problèmes et de codage difficile s'ils tentent de le réimplémenter par eux-mêmes.
Sam Watkins

Réponses:


190

( Avertissement: je suis l'auteur de SlickGrid )

MISE À JOUR Ceci a maintenant été implémenté dans SlickGrid .

Veuillez consulter http://github.com/mleibman/SlickGrid/issues#issue/22 pour une discussion en cours sur le fonctionnement de SlickGrid avec un plus grand nombre de lignes.

Le problème est que SlickGrid ne virtualise pas la barre de défilement elle-même - la hauteur de la zone de défilement est définie sur la hauteur totale de toutes les lignes. Les lignes sont toujours ajoutées et supprimées lorsque l'utilisateur fait défiler, mais le défilement lui-même est effectué par le navigateur. Cela lui permet d'être très rapide mais fluide (les événements de défilement sont notoirement lents). La mise en garde est qu'il existe des bogues / limites dans les moteurs CSS des navigateurs qui limitent la hauteur potentielle d'un élément. Pour IE, cela se trouve être 0x123456 ou 1193046 pixels. Pour les autres navigateurs, il est plus élevé.

Il existe une solution de contournement expérimentale dans la branche «largenum-fix» qui augmente cette limite de manière significative en remplissant la zone de défilement avec des «pages» définies à une hauteur de 1 M pixels, puis en utilisant un positionnement relatif dans ces pages. Étant donné que la limite de hauteur dans le moteur CSS semble être différente et nettement inférieure à celle du moteur de disposition réel, cela nous donne une limite supérieure beaucoup plus élevée.

Je cherche toujours un moyen d'accéder à un nombre illimité de lignes sans renoncer à l'avantage de performance que SlickGrid détient actuellement par rapport aux autres implémentations.

Rudiger, pouvez-vous expliquer comment vous avez résolu cela?


1
J'ai trouvé que SlickGrid était le plus attrayant - surtout si l'on travaille avec jQuery. Félicitations! (surtout pour la grande attitude et la persévérance.) :-)
Andras Vass

J'essaie d'utiliser slickgrid pour afficher les en-têtes Excel, et je constate qu'en ayant trop de colonnes, slickgrid optimise uniquement le défilement des lignes et non des colonnes. J'ai également remarqué que lorsque plus de 120 colonnes sont présentes, slickgrid place les nouvelles lignes dans une nouvelle ligne. Le nombre maximal de lignes peut-il être défini quelque part dans les fichiers?
oneiros

1
SlickGrid v2.1 utilise le défilement virtuel pour les colonnes ainsi que les lignes. De plus, le problème des colonnes débordantes a été résolu.
Tin

@Tin - Ceci est similaire à mon approche; J'avais des années d'avance sur mon temps! "Une primitive de mise en page de blocs paresseux pour créer un défilement infini dans les applications Web." docs.google.com/document/d/…
Rudiger

@Rudiger Oui, je l'ai vu sur le groupe Blink il y a environ un mois, mais je ne sais pas trop comment cela s'intègre dans l'image. La mise en page paresseuse fonctionne sur des éléments réellement présents dans le DOM, ce que nous ne pouvons pas vraiment faire. Veuillez développer :)
Tin

84

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

" SlickGrid utilise le rendu virtuel pour vous permettre de travailler facilement avec des centaines de milliers d'éléments sans aucune baisse de performances. En fait, il n'y a pas de différence de performances entre travailler avec une grille de 10 lignes et 100'000 lignes. "

Quelques faits saillants:

  • Défilement virtuel adaptatif (gérer des centaines de milliers de lignes)
  • Vitesse de rendu extrêmement rapide
  • Post-rendu en arrière-plan pour les cellules plus riches
  • Configurable et personnalisable
  • Navigation clavier complète
  • Redimensionner / réorganiser / afficher / masquer la colonne
  • Dimensionnement automatique et ajustement forcé de la colonne
  • Formateurs et éditeurs de cellules enfichables
  • Prise en charge de l'édition et de la création de nouvelles lignes. "par mleibman

C'est gratuit (licence MIT). Il utilise jQuery.


Cela fonctionne très bien jusqu'à 131 001 lignes précisément ... Autrement dit, il y a une ligne de code comme celle-ci: data.length = Math.min(131000, parseInt(resp.total));... Et, bien sûr, codée en dur pour une raison :(
Rudiger

6
Cela a pris un peu de travail, mais j'ai apporté quelques modifications pour rendre la grille indépendante de la longueur du datatableau. C'est un kludge, mais j'ai les réponses qui peuplent un bigdatatableau, et les plus petits datatirages du bigdatatableau. Le reste du programme utilise le plus petit tableau de données, à l'exception de la mesure de la barre de défilement et de quelques autres emplacements qui sont désormais illimités pour un grand nombre de lignes. Dans l'ensemble, c'était beaucoup plus facile que d'écrire le mien.
Rudiger

8
@Rudiger: SlickGrid prend désormais en charge un nombre illimité de lignes en mode natif. Voir github.com/mleibman/SlickGrid/tree/unlimited-rows . Une fois que cela sera testé à fond, il sera fusionné dans la branche principale.
Tin

J'essaie d'utiliser slickgrid pour afficher les en-têtes Excel, et je constate qu'en ayant trop de colonnes, slickgrid optimise uniquement le défilement des lignes et non des colonnes. J'ai également remarqué que lorsque plus de 120 colonnes sont présentes, slickgrid place les nouvelles lignes dans une nouvelle ligne. Le nombre maximal de lignes peut-il être défini quelque part dans les fichiers?
oneiros

si vous voulez quelque chose de très rapide, ne comptez pas sur quoi que ce soit qui utilise jquery pour faire des choses dans le noyau, et utilisez plutôt innerHTML que DOM append. Les barres de défilement Javascript peuvent être plus lentes que les barres de défilement du navigateur sur les ordinateurs lents, évitez les règles CSS complexes et vous devriez passer du temps à simplifier la présentation d'une seule ligne. Les micro-optimisations pourraient être significatives dans ce cas. Ce ne sont que des pratiques générales pour améliorer les performances. jsPerf.com est votre ami.
Vitim.us

37

Les meilleures grilles à mon avis sont ci-dessous:

Mes 3 meilleures options sont jqGrid, jqxGrid et DataTables. Ils peuvent fonctionner avec des milliers de lignes et prendre en charge la virtualisation.


1
+1 pour la liste, bien qu'il n'y ait pas grand-chose en termes de comparaison. Un bon début serait d'ajouter le nombre de commits pour chacun - 33 pour Flexigrid à partir de maintenant, contre 491 pour SlickGrid.
Dan Dascalescu

12
Vissez la limite d'édition de commentaires de 5 minutes de SO. # 1 - jqGrid - 1000+ commits ; # 2 - 752 pour DataTables ; # 3-491 pour SlickGrid ; # 4 - 33 s'engage pour Flexigrid . Ingrid - aucune mise à jour depuis juin 2011 . jqGridView - aucune mise à jour depuis 2009
Dan Dascalescu

3
Sur la base du commentaire précédent, j'inclus ici le nombre de fourches par projet: # 1 - SlickGrid - 670 fourches; # 2 - jqGrid - 358 fourchettes; # 3 - Flexigrid - 238; # 4 - DataTables - 216; # 5 - Ingrid - 41; # 6 - jqGridView - 0;
ljs.dev

1

Puis-je dire que Slickgrid est toujours bien vivant, mais le dépôt Mleibman cité ci-dessus est mort. Nouveau lien: github.com/6pac/SlickGrid (mleibman y fait référence dans une note finale sur son repo), ou www.slickgrid.net
Ben McIntyre

25

Je ne veux pas déclencher une guerre des flammes, mais en supposant que vos chercheurs sont humains, vous ne les connaissez pas aussi bien que vous le pensez. Ce n'est pas parce qu'ils ont des pétaoctets de données qu'ils sont capables de visualiser même des millions d'enregistrements de manière significative. Ils pourraient dire qu'ils veulent voir des millions de disques, mais c'est tout simplement stupide. Demandez à vos chercheurs les plus intelligents de faire quelques calculs de base: Supposons qu'ils passent 1 seconde à regarder chaque enregistrement. À ce rythme, cela prendra 1000000 secondes, ce qui correspond à plus de six semaines (de 40 heures de travail sans interruption pour la nourriture ou les toilettes).

Pensent-ils (ou vous) sérieusement qu'une seule personne (celle qui regarde la grille) peut rassembler ce genre de concentration? Sont-ils vraiment en train de faire beaucoup de choses au cours de cette seconde, ou filtrent-ils (plus probablement) les trucs qu'ils ne font pas veulent ? Je soupçonne qu'après avoir visionné un sous-ensemble "de taille raisonnable", ils pourraient vous décrire un filtre qui filtrerait automatiquement ces enregistrements.

Comme paxdiablo et Sleeper Smith et Lasse V Karlsen l'ont également laissé entendre, vous (et eux) n'avez pas réfléchi aux exigences. Du côté positif, maintenant que vous avez trouvé SlickGrid, je suis sûr que le besoin de ces filtres est devenu immédiatement évident.


2
Avoir besoin de millions de lignes ne signifie pas toujours les consulter. Parfois, les clients souhaitent un vidage partiel des enregistrements à exécuter dans leurs propres systèmes d'analyse de données.
cbmeeks

10
S'il s'agit d'un vidage de données pour leur propre analyse, il ne serait pas affiché dans une grille sur une page Web, n'est-ce pas?
Steven Benitez

5
je n'ai pas besoin de les voir tous en même temps. C'est à cela que Ctrl+Fservent le tri des colonnes . L'alternative (pagination, recherche de site Web) est bien pire. Regardez simplement StackOverflow lorsque vous essayez de faire défiler les questions ou les réponses, Reddit pour faire défiler l'historique des commentaires d'un utilisateur. Le tri et la recherche instantanée fournissent une puissance dont dispose l'Explorateur Windows, mais les sites Web manquent.
Ian Boyd

15

Je peux dire avec une assez bonne certitude que vous n'avez vraiment pas besoin de montrer des millions de lignes de données à l'utilisateur.

Aucun utilisateur au monde ne pourra comprendre ou gérer cet ensemble de données, donc même si vous réussissez techniquement à le retirer, vous ne résoudrez aucun problème connu pour cet utilisateur.

Au lieu de cela, je me concentrerais sur la raison pour laquelle l'utilisateur souhaite voir les données. L'utilisateur ne veut pas voir les données juste pour voir les données, il y a généralement une question posée. Si vous vous concentrez plutôt sur la réponse à ces questions, vous serez alors beaucoup plus proche de quelque chose qui résout un problème réel.


16
Mes utilisateurs sont des chercheurs habitués aux pétaoctets de données. Je pense que je connais mes utilisateurs un peu mieux que vous, même si vous avez certainement raison dans le cas général. Quant au pourquoi , cette grille de données fait simplement partie d'un ensemble d'outils pour gérer le big data.
Rudiger

7

Je recommande l'Ext JS Grid avec la fonction Buffered View.

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


ExtJs, en effet. Il est essentiellement conçu spécialement pour la présentation des données
KdgDev

1
ExtJs est si bon que je veux pleurer que ce n'est pas construit sur jQuery
James Westgate

Vous pouvez maintenant charger uniquement les parties liées à la grille d'ExtJS, afin que l'ajout d'une grille ExtJS à votre application ne soit pas trop lourd. Cependant, vous devez toujours prendre en compte les différences d'apparence et utiliser la manière ExtJS de thématiser uniquement ce composant.
JD Smith

7

(Avertissement: je suis l'auteur de w2ui)

J'ai récemment écrit un article sur la façon d'implémenter une grille JavaScript avec 1 million d'enregistrements ( http://w2ui.com/web/blog/7/JavaScript-Grid-with-One-Million-Records ). J'ai découvert qu'en fin de compte il y a 3 restrictions qui empêchent de le prendre plus haut:

  1. La hauteur du div a une limite (peut être surmontée par un défilement virtuel)
  2. Les opérations telles que le tri et la recherche commencent à être lentes après environ un million d'enregistrements
  3. La RAM est limitée car les données sont stockées dans un tableau JavaScript

J'ai testé la grille avec 1 million d'enregistrements (sauf IE) et elle fonctionne bien. Voir l'article pour des démos et des exemples.


Avec ce million d'enregistrements, votre page html a une taille de 3 Mo, mais quand je charge mes données, la page est de 15 Mo, est-ce que w2ui peut gérer cela? J'ai besoin de toutes les données pour certains calculs.
Chetan S. Choudhary

6

dojox.grid.DataGrid propose une abstraction JS pour les données afin que vous puissiez les connecter à divers backends avec les magasins dojo.data fournis ou écrire les vôtres. Vous en aurez évidemment besoin d'un qui prend en charge l'accès aléatoire pour ces nombreux enregistrements. DataGrid fournit également une accessibilité complète.

Modifiez donc voici un lien vers l'article de Matthew Russell qui devrait fournir l'exemple dont vous avez besoin, en affichant des millions d'enregistrements avec dojox.grid. Notez qu'il utilise l'ancienne version de la grille, mais les concepts sont les mêmes, il y avait juste quelques améliorations d'API incompatibles.

Oh, et c'est open source totalement gratuit.



4

Voici quelques optimisations que vous pouvez appliquer pour accélérer les choses. Je pense juste à haute voix.

Étant donné que le nombre de lignes peut être de plusieurs millions, vous souhaiterez un système de mise en cache uniquement pour les données JSON du serveur. Je ne peux pas imaginer que quelqu'un veuille télécharger tous les X millions d'articles, mais s'ils le faisaient, ce serait un problème. Ce petit test sur Chrome pour un tableau sur 20M + entiers plante en permanence sur ma machine.

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

Vous pouvez utiliser LRU ou un autre algorithme de mise en cache et avoir une limite supérieure sur la quantité de données que vous êtes prêt à mettre en cache.

Pour les cellules du tableau elles-mêmes, je pense que la construction / destruction de nœuds DOM peut être coûteuse. Au lieu de cela, vous pouvez simplement prédéfinir le nombre X de cellules, et chaque fois que l'utilisateur fait défiler vers une nouvelle position, injectez les données JSON dans ces cellules. La barre de défilement n'aurait pratiquement aucune relation directe avec l'espace (hauteur) requis pour représenter l'ensemble de données entier. Vous pouvez définir arbitrairement la hauteur du conteneur de table, disons 5000 px, et la mapper au nombre total de lignes. Par exemple, si la hauteur des conteneurs est de 5000 pixels et qu'il y a un total de 10 millions de lignes, alors starting row ≈ (scroll.top/5000) * 10Mscroll.topreprésente la distance de défilement à partir du haut du conteneur. Petite démo ici .

Pour détecter quand demander plus de données, idéalement, un objet doit agir comme un médiateur qui écoute les événements de défilement. Cet objet garde une trace de la vitesse de défilement de l'utilisateur, et lorsqu'il semble que l'utilisateur ralentit ou s'est complètement arrêté, effectue une demande de données pour les lignes correspondantes. La récupération de données de cette manière signifie que vos données vont être fragmentées, donc le cache doit être conçu dans cet esprit.

Les limites du navigateur sur le nombre maximal de connexions sortantes peuvent également jouer un rôle important. Un utilisateur peut faire défiler jusqu'à une certaine position qui déclenchera une demande AJAX, mais avant cela, l'utilisateur peut faire défiler jusqu'à une autre partie. Si le serveur ne répond pas suffisamment, les demandes seront mises en file d'attente et l'application ne répondra pas. Vous pouvez utiliser un gestionnaire de demandes par lequel toutes les demandes sont acheminées et il peut annuler les demandes en attente pour libérer de l'espace.


4

Je sais que c'est une vieille question mais quand même. Il y a aussi dhtmlxGrid qui peut gérer des millions de lignes. Il y a une démo avec 50 000 lignes mais le nombre de lignes qui peuvent être chargées / traitées dans la grille est illimité.

Avertissement: je suis de l'équipe DHTMLX.


Je veux afficher 10 Mo de données Json et je veux l'utiliser dans le calcul, DHTMLX peut-il faire cette chose, Avec ces données et balises html, la page de mon navigateur est d'environ 15 Mo. Cela vaut-il la peine d'utiliser DHTMLX?
Chetan S. Choudhary


3

Avertissement: j'utilise fortement YUI DataTable sans aucun mal de tête pendant une longue période . Il est puissant et stable. Pour vos besoins, vous pouvez utiliser un ScrollingDataTable qui prend en charge

  • défilement x
  • défilement y
  • défilement xy
  • Un puissant mécanisme d'événement

Pour ce dont vous avez besoin, je pense que vous voulez est un tableScrollEvent . Son API dit

Déclenché lorsqu'un DataTable à défilement fixe a un défilement.

Comme chaque DataTable utilise un DataSource, vous pouvez surveiller ses données via tableScrollEvent avec la taille de la boucle de rendu afin de remplir votre ScrollingDataTable selon vos besoins.

La taille de la boucle de rendu indique

Dans les cas où votre DataTable doit afficher l'intégralité d'un très grand ensemble de données, la configuration renderLoopSize peut aider à gérer le rendu DOM du navigateur afin que le thread d'interface utilisateur ne soit pas verrouillé sur de très grandes tables . Toute valeur supérieure à 0 entraînera l'exécution du rendu DOM dans les chaînes setTimeout () qui rendent le nombre spécifié de lignes dans chaque boucle. La valeur idéale doit être déterminée par implémentation car il n'y a pas de règles strictes et rapides, seulement des directives générales:

  • Par défaut, renderLoopSize est 0, donc toutes les lignes sont rendues dans une seule boucle. Un renderLoopSize> 0 ajoute des frais généraux, donc utilisez-le soigneusement.
  • Si votre ensemble de données est suffisamment volumineux (nombre de lignes X nombre de colonnes X complexité de formatage) que les utilisateurs subissent une latence dans le rendu visuel et / ou si le script se bloque , envisagez de définir un renderLoopSize .
  • Un renderLoopSize de moins de 50 ans n'en vaut probablement pas la peine. Un renderLoopSize> 100 est probablement mieux.
  • Un ensemble de données n'est probablement pas considéré comme suffisamment volumineux à moins qu'il ne comporte des centaines et des centaines de lignes.
  • Le fait d'avoir un renderLoopSize> 0 et <total des lignes entraîne le rendu de la table dans une boucle (identique à renderLoopSize = 0) mais il déclenche également des fonctionnalités telles que l'entrelacement des lignes après le rendu à gérer à partir d'un thread setTimeout distinct.

Par exemple

// 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> n'est qu'une seule DataSource . Il peut s'agir d'un élément JSON, JSFunction, XML et même d'un seul élément HTML

Ici vous pouvez voir un tutoriel simple, fourni par moi. Sachez qu'aucun autre pluglin DATA_TABLE ne prend en charge les clics simple et double en même temps. YUI DataTable vous le permet. Et en plus, vous pouvez l'utiliser même avec JQuery sans aucun mal de tête

Quelques exemples, vous pouvez voir

N'hésitez pas à poser des questions sur tout ce que vous voulez à propos de YUI DataTable.

Cordialement,


3

Je ne parviens pas à voir le point, pour jqGrid, vous pouvez utiliser la fonctionnalité de défilement virtuel:

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

mais là encore, des millions de lignes avec filtrage peuvent être effectuées:

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

Je ne vois vraiment pas l'intérêt de "comme s'il n'y avait pas de pages", je veux dire ... il n'y a aucun moyen d'afficher 1 000 000 de lignes à la fois dans le navigateur - c'est 10 Mo de HTML brut, je ne parviens pas à voir pourquoi les utilisateurs ne voudraient pas voir les pages.

En tous cas...


2

la meilleure approche à laquelle je pourrais penser est de charger le bloc de données au format json pour chaque défilement ou une limite avant la fin du défilement. json peut être facilement converti en objets et, par conséquent, les lignes de table peuvent être construites facilement et discrètement


Voilà comment je l'ai. Une demande est faite pour un ensemble de lignes renvoyées en JSON ... Je suis à la recherche d'un moteur de rendu côté client javascript qui prend en charge cela!
Rudiger

Quoi??? Qu'est-ce que le "moteur de rendu du site client"? Tout javascript devra toujours effectuer un appel ajax - vous devrez donc vous contenter d'un certain format de transport. Vous ne pouvez pas échapper au travail. Personne ne fera ça pour toi mon ami.
Andriy Drozdyuk

1
Je sais qu'un appel AJAX doit être fait; cette partie est simple. Le client demande quelque chose comme "start = 20 & limit = 20" et récupère les lignes 20-39 du serveur (format XML ou JSON). Le "moteur de rendu côté client" (ma terminologie!) Effectue ces requêtes de manière intelligente (par exemple lorsque l'utilisateur fait défiler vers le bas) et affiche les résultats de manière transparente dans une jolie grille. Contrairement à ce que vous dites, quelqu'un d'autre a fait ce travail pour moi. C'est ce que sont toutes les autres réponses à cette question.
Rudiger

Eh bien, il semble que personne "d'autre" ne l'ait fait pour vous :)
Andriy Drozdyuk

1

Je recommanderais vivement Open rico . Il est difficile à mettre en œuvre au début, mais une fois que vous l'aurez saisi, vous ne regarderez jamais en arrière.




0

Jetez un œil à dGrid:

https://dgrid.io/

Je suis d'accord que les utilisateurs ne verront JAMAIS, JAMAIS des millions de lignes de données à la fois, mais dGrid peut les afficher rapidement (un écran à la fois).

Ne faites pas bouillir l'océan pour faire une tasse de thé.


votre tasse de thé (lien) est introuvable. :)
Akshay

Il a son propre site maintenant :)
ColemanTO
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.