web-dev-qa-db-fra.com

Grille de données JavaScript pour des millions de lignes

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

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

Au contraire, il devrait sembler que toutes les données sont disponibles.

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

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

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

222
Rudiger

( Avertissement: je suis l'auteur de SlickGrid )

UPDATE Ceci a maintenant été implémenté dans SlickGrid .

Veuillez consulter http://github.com/mleibman/SlickGrid/issues#issue/22 pour une discussion en cours sur la façon de faire fonctionner 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 à mesure que 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 et fluide (les événements onscroll sont notoirement lents). La mise en garde est qu'il existe des bugs/limites dans les moteurs CSS des navigateurs qui limitent la hauteur potentielle d'un élément. Pour IE, il s’agit de 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 soulève cette limite de manière significative en renseignant la zone défilable avec des "pages" réglées sur 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 présentation actuel, la limite supérieure est beaucoup plus élevée.

Je suis toujours à la recherche d'un moyen d'obtenir un nombre illimité de lignes sans abandonner les performances que présente actuellement SlickGrid par rapport à d'autres implémentations.

Rudiger, pouvez-vous nous expliquer comment vous avez résolu ce problème?

190
Tin

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 perte de performance. En fait, il n'y a aucune différence de performance entre le fait de travailler avec une grille de 10 lignes '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 des cellules plus riches
  • Configurable et personnalisable
  • Navigation complète au clavier
  • Colonne redimensionner/réorganiser/afficher/masquer
  • ajustement automatique de la colonne et ajustement forcé
  • Formateurs et éditeurs de cellules enfichables
  • Prise en charge de l'édition et de la création de nouvelles lignes. "by mleibman

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

84
Andras Vass

Les meilleures grilles à mon avis sont ci-dessous:

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

35
scripto

Je ne veux pas déclencher une guerre des flammes, mais si vos chercheurs sont humains, vous ne les connaissez pas aussi bien que vous le pensez. Le simple fait qu'ils possèdent des pétaoctets de données ne les rend pas capables de visualiser des millions d'enregistrements de manière significative. Ils pourraient dire qu'ils veulent voir des millions d'enregistrements, mais c'est idiot. Demandez à vos chercheurs les plus intelligents de faire des calculs élémentaires: supposons qu’ils passent 1 seconde à visionner chaque enregistrement. À ce rythme, cela prendra 1 000 secondes, ce qui correspond à plus de six semaines (sur une période de travail de 40 heures sans pause pour la nourriture ou les toilettes).

Est-ce qu'ils (ou vous-même) pensez sérieusement qu'une personne (celle qui regarde la grille) peut rassembler ce genre de concentration? Sont-ils vraiment en train de faire beaucoup en une seconde ou sont-ils (plus susceptibles) en train de filtrer les éléments que ne veulent pas ? Je soupçonne qu'après avoir consulté 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. Sur le plan positif, maintenant que vous avez trouvé SlickGrid, je suis sûr que la nécessité de ces filtres est devenue évidente.

25

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

Aucun utilisateur au monde ne sera en mesure de comprendre ou de gérer cet ensemble de données. Ainsi, même si vous parvenez techniquement à le retirer, vous ne résolvez aucun problème connu pour cet utilisateur.

Au lieu de cela, je me concentrerais sur pourquoi l'utilisateur veut 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 les réponses à ces questions, vous serez alors beaucoup plus près de quelque chose qui résout un problème réel.

Je recommande la grille Ext JS avec la fonction Buffered View.

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

7
richardtallent

(Avertissement: je suis l'auteur de w2ui)

J'ai récemment écrit un article sur la façon de mettre en œuvre 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 prendre de la hauteur:

  1. La hauteur de la div a une limite (peut être surmontée par défilement virtuel)
  2. Les opérations telles que le tri et la recherche commencent à être lentes après environ 1 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émonstrations et des exemples.

6
vitmalina

dojox.grid.DataGrid offre une abstraction JS pour les données afin que vous puissiez la relier à divers backends avec les magasins fournis dojo.data ou écrire votre propre. Vous en aurez évidemment besoin d’un qui prend en charge l’accès aléatoire pour ce nombre d’enregistrements. DataGrid fournit également une accessibilité complète.

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

Oh, et c'est open source totalement gratuit.

6
peller

Voici quelques optimisations que vous pouvez appliquer pour accélérer les choses. Juste penser à voix haute.

Étant donné que le nombre de lignes peut être plusieurs millions, vous souhaiterez un système de mise en cache uniquement pour les données JSON du serveur. Je ne peux imaginer que quiconque veuille télécharger X millions d'articles, mais si c'était le cas, ce serait un problème. Ce petit test sur Chrome pour un tableau sur 20M + entiers plante constamment 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 définir une limite supérieure sur la quantité de données que vous souhaitez mettre en cache.

Pour les cellules de 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 un nombre X de cellules et, chaque fois que l'utilisateur fait défiler jusqu'à une nouvelle position, injecter les données JSON dans ces cellules. La barre de défilement n’aurait pratiquement aucune relation directe avec la quantité d’espace (hauteur) requise pour représenter l’ensemble du jeu de données. Vous pouvez définir arbitrairement la hauteur du conteneur de la table, par exemple 5000 px, et la mapper sur le nombre total de lignes. Par exemple, si la hauteur du conteneur est de 5000 pixels et qu'il y a un total de 10 millions de lignes, la starting row ≈ (scroll.top/5000) * 10Mscroll.top représente la distance de défilement du haut du conteneur. Petite démo ici .

Pour détecter le moment où demander plus de données, un objet devrait idéalement agir en tant que médiateur écoutant les événements de défilement. Cet objet enregistre la vitesse de défilement de l'utilisateur et, lorsqu'il semble que l'utilisateur est en train de ralentir ou est complètement arrêté, effectue une demande de données pour les lignes correspondantes. Récupérer les données de cette manière signifie que vos données vont être fragmentées, le cache doit donc être conçu dans cet esprit.

De plus, les limites du nombre maximal de connexions sortantes imposées par le navigateur peuvent jouer un rôle important. Un utilisateur peut faire défiler jusqu'à une certaine position, ce qui déclenchera une demande AJAX, mais avant la fin, l'utilisateur peut faire défiler jusqu'à une autre partie. Si le serveur n'est pas suffisamment réactif, les demandes sont mises en file d'attente et l'application semble ne pas répondre. Vous pouvez utiliser un gestionnaire de demandes via lequel toutes les demandes sont routées et il peut annuler les demandes en attente afin de libérer de l'espace.

4
Anurag

J'ai utilisé jQuery Grid Plugin , c'était agréable.

Démos

4
Amr Elgarhy

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 pouvant être chargées/traitées dans la grille est illimité.

Disclaimer: Je fais partie de l'équipe DHTMLX.

4
Paul

Je ne vois pas très bien le problème. 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 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...

3
user125775
3
ant

Avertissement: i fortement utiliser YUI DataTable sans aucun mal de tête pendant longtemps . C'est puissant et stable. Pour vos besoins, vous pouvez utiliser un ScrollingDataTable wich

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

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

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

Comme chaque DataTable utilise une source de données , vous pouvez surveiller ses données via tableScrollEvent ainsi que la taille de la boucle de rendu afin de renseigner 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 de 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 grands tableaux. . Toute valeur supérieure à 0 entraîne l'exécution du rendu DOM dans les chaînes setTimeout () qui affichent le nombre de lignes spécifié dans chaque boucle. La valeur idéale doit être déterminée par mise en œuvre car il n'y a pas de règles strictes, mais seulement des directives générales:

  • La valeur par défaut de renderLoopSize est 0. Toutes les lignes sont donc rendues dans une seule boucle. RenderLoopSize> 0 ajoute une surcharge, utilisez donc judicieusement.
  • Si votre ensemble de données est suffisamment volumineux (nombre de lignes X nombre de colonnes X complexité de formatage), les utilisateurs subissent une latence dans le rendu visuel et/ou provoque le blocage du script envisagez de définir un renderLoopSize .
  • Un renderLoopSize inférieur à 50 n'est probablement pas la peine. RenderLoopSize> 100 est probablement mieux.
  • Un ensemble de données n'est probablement pas considéré comme assez volumineux, sauf s'il comporte des centaines et des centaines de lignes.
  • Le fait d'avoir renderRoopSize> 0 et <total de lignes entraîne le rendu de la table dans une boucle (identique à renderLoopSize = 0), mais déclenche également des fonctionnalités telles que la segmentation de lignes post-rendu à partir d'un thread setTimeout séparé.

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’un seul source de données . Cela peut être un JSON, JSFunction, XML et même un seul élément HTML

Ici vous pouvez voir un tutoriel simple, fourni par moi. Sachez que aucun autre DATA_TABLE pluglin ne prend en charge que les clics simple et double en même temps. YUI DataTable vous permet. Et plus encore , 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 sur YUI DataTable.

cordialement,

3
Arthur Ronald

la meilleure approche à laquelle je puisse 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 donc les rangées de table peuvent être construites facilement et discrètement

2
coder

Je sais que cette question date de quelques années, mais jqgrid prend désormais en charge le défilement virtuel:

http://www.trirand.com/blog/phpjqgrid/examples/paging/scrollbar/default.php

mais avec la pagination désactivée

1
sksallaj

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

1
mosid

Je suggère que sigma grid, sigma grid intègre des fonctions de pagination pouvant prendre en charge des millions de lignes. Et aussi, vous aurez peut-être besoin d'une pagination à distance pour le faire. voir la démo http://www.sigmawidgets.com/products/sigma_grid2/demos/example_master_details.html

0
Bussy

Jetez un coup d'œil à dGrid:

https://dgrid.io/

Je conviens que les utilisateurs n'auront JAMAIS, JAMAIS besoin d'afficher des millions de lignes de données en même temps, mais dGrid peut les afficher rapidement (un écran à la fois).

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

0
ColemanTO