Cuadrícula de datos de JavaScript para millones de filas [cerrado]


225

Necesito presentar una gran cantidad de filas de datos (es decir, millones de filas) al usuario en una cuadrícula usando JavaScript.

El usuario no debe ver páginas o ver solo cantidades finitas de datos a la vez.

Más bien, debería parecer que todos los datos están disponibles.

En lugar de descargar todos los datos de una vez, se descargan pequeños fragmentos a medida que el usuario se acerca a ellos (es decir, desplazándose por la cuadrícula).

Las filas no se editarán a través de este front-end, por lo que se aceptan cuadrículas de solo lectura.

¿Qué cuadrículas de datos, escritas en JavaScript, existen para este tipo de paginación perfecta?


1
No acepté la respuesta jqgrid, ya que parece fallar para grandes conjuntos de datos ... ¿Alguna otra sugerencia? ¿Qué pasa con ext-livegrid.com ?
Rudiger

66
Escribe lo tuyo. Estoy seguro de que los otros se están ahogando porque simplemente siguen agregándose al DOM. Creo que necesitará una solución que elimine las filas a medida que se desplazan fuera de la pantalla. Esa es la única manera. Simplemente no puede tener un millón de filas de tablas en el DOM y esperar que cada navegador se muestre y se desplace sin problemas en todos los entornos. Sé razonable.
Josh Stodola

2
@Rudiger: SlickGrid ahora admite un número ilimitado de filas de forma nativa. Ver github.com/mleibman/SlickGrid/tree/unlimited-rows . Una vez que esto se pruebe a fondo, se fusionará con la rama principal.
Estaño

10
Y siento pena por la firma para la que trabajas. Para su información, una pantalla de 1920x1080 con solo 1 millón de filas, saltará 20 filas por cada píxel de movimiento en la barra de desplazamiento. Realice algunas pruebas de usabilidad en lugar de perder el tiempo.
Sleeper Smith

2
Esta pregunta y sus dos respuestas principales (al menos) son extremadamente útiles. Podría haber atraído algunas respuestas de baja calidad, pero de ninguna manera esta pregunta debería cerrarse. El uso de SlickGrid para resolver este problema puede ahorrarle a las personas muchas horas de problemas y codificación difícil, si intentan volver a implementar esto por sí mismos.
Sam Watkins

Respuestas:


190

( Descargo de responsabilidad: soy el autor de SlickGrid )

ACTUALIZACIÓN Esto ahora se ha implementado en SlickGrid .

Consulte http://github.com/mleibman/SlickGrid/issues#issue/22 para una discusión continua sobre cómo hacer que SlickGrid funcione con un mayor número de filas.

El problema es que SlickGrid no virtualiza la barra de desplazamiento: la altura del área desplazable se establece en la altura total de todas las filas. Las filas se siguen agregando y eliminando a medida que el usuario se desplaza, pero el navegador realiza el desplazamiento en sí. Eso permite que sea muy rápido pero suave (los eventos de desplazamiento son notoriamente lentos). La advertencia es que hay errores / límites en los motores CSS de los navegadores que limitan la altura potencial de un elemento. Para IE, eso es 0x123456 o 1193046 píxeles. Para otros navegadores es más alto.

Hay una solución experimental en la rama "arreglo de largenum" que aumenta ese límite de manera significativa al llenar el área desplazable con "páginas" establecidas en 1 M de altura de píxeles y luego usar el posicionamiento relativo dentro de esas páginas. Dado que el límite de altura en el motor CSS parece ser diferente y significativamente más bajo que en el motor de diseño real, esto nos da un límite superior mucho más alto.

Todavía estoy buscando una manera de llegar a un número ilimitado de filas sin renunciar a la ventaja de rendimiento que SlickGrid tiene actualmente sobre otras implementaciones.

Rudiger, ¿puedes explicar cómo resolviste esto?


1
He descubierto que SlickGrid es el más atractivo, especialmente si uno trabaja con jQuery. Felicidades! (especialmente por la gran actitud y persistencia.) :-)
Andras Vass el

Estoy tratando de usar slickgrid para mostrar encabezados de Excel, y veo que cuando tengo demasiadas columnas, slickgrid solo optimiza el desplazamiento de las filas y no de las columnas. También he notado que al tener más de 120 columnas más o menos, slickgrid coloca las nuevas filas en una nueva línea. ¿Se puede establecer el número máximo de filas en algún lugar de los archivos?
oneiros

1
SlickGrid v2.1 tiene un desplazamiento virtual para columnas y filas. Además, el problema de columnas desbordantes se ha resuelto.
Estaño

@Tin - Esto es similar a mi enfoque; ¡Estaba años adelantado a mi tiempo! "Una primitiva de diseño de bloque perezoso para construir desplazamiento infinito en aplicaciones web". docs.google.com/document/d/…
Rudiger

@Rudiger Sí, he visto esto en el grupo Blink hace aproximadamente un mes, pero no estoy muy seguro de cómo encaja esto en la imagen. El diseño diferido opera en elementos realmente presentes en el DOM, lo que realmente no podemos hacer. Por favor explique :)
Estaño

84

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

" SlickGrid utiliza renderizado virtual para permitirle trabajar fácilmente con cientos de miles de elementos sin ninguna caída en el rendimiento. De hecho, no hay diferencia en el rendimiento entre trabajar con una cuadrícula con 10 filas frente a 100,000 filas " .

Algunos puntos destacados:

  • Desplazamiento virtual adaptativo (maneja cientos de miles de filas)
  • Velocidad de renderizado extremadamente rápida
  • Fondo posterior a la representación para celdas más ricas
  • Configurable y personalizable
  • Teclado completo de navegación
  • Cambiar el tamaño de la columna / reordenar / mostrar / ocultar
  • Columna autosizing y ajuste forzado
  • Formateadores y editores de células conectables
  • Soporte para editar y crear nuevas filas. "por mleibman

Es gratis (licencia MIT). Utiliza jQuery.


Funciona bien hasta exactamente 131.001 filas ... Es decir, hay una línea de código como esta: data.length = Math.min(131000, parseInt(resp.total));... Y, por supuesto, eso está codificado por una razón :(
Rudiger

66
Tomó un poco de trabajo, pero hice algunos cambios para hacer que la cuadrícula sea independiente de la longitud de la datamatriz. Es un error, pero tengo las respuestas que pueblan una bigdatamatriz, y las dataextracciones más pequeñas de la bigdatamatriz. El resto del programa utiliza la matriz de datos más pequeña, a excepción de la medición de la barra de desplazamiento y algunos otros lugares que ahora están sin límites para una gran cantidad de filas. En general, fue mucho más fácil que escribir el mío.
Rudiger

8
@Rudiger: SlickGrid ahora admite un número ilimitado de filas de forma nativa. Ver github.com/mleibman/SlickGrid/tree/unlimited-rows . Una vez que esto se pruebe a fondo, se fusionará con la rama principal.
Estaño

Estoy tratando de usar slickgrid para mostrar encabezados de Excel, y veo que cuando tengo demasiadas columnas, slickgrid solo optimiza el desplazamiento de las filas y no de las columnas. También he notado que al tener más de 120 columnas más o menos, slickgrid coloca las nuevas filas en una nueva línea. ¿Se puede establecer el número máximo de filas en algún lugar de los archivos?
oneiros

si quieres algo realmente rápido, no confíes en nada que use jquery para hacer cosas en el núcleo, y más bien usa innerHTML que DOM anexar. Las barras de desplazamiento de Javascript pueden ser notablemente más lentas que las barras de desplazamiento del navegador en computadoras lentas, evite las complejas reglas de CSS, y debe pasar tiempo simplificando el diseño de una sola fila. Las micro optimizaciones podrían ser significativas en este caso. Estas son solo prácticas generales para mejorar el rendimiento. jsPerf.com es tu amigo.
Vitim.us

37

Las mejores cuadrículas en mi opinión están a continuación:

Mis 3 mejores opciones son jqGrid, jqxGrid y DataTables. Pueden trabajar con miles de filas y admitir la virtualización.


1
+1 para la lista, aunque no hay mucho en términos de comparación. Un buen comienzo sería agregar el número de confirmaciones para cada uno: 33 para Flexigrid a partir de ahora, frente a 491 para SlickGrid.
Dan Dascalescu

12
Atornille el límite de edición de comentarios de 5 minutos de SO. # 1 - jqGrid - 1000+ confirmaciones ; # 2 - 752 para DataTables ; # 3 - 491 para SlickGrid ; # 4 - 33 commits para Flexigrid . Ingrid: sin actualización desde junio de 2011 . jqGridView - sin actualización desde 2009
Dan Dascalescu

3
Sobre la base del comentario anterior, incluyo el número de horquillas por proyecto aquí: # 1 - SlickGrid - 670 horquillas; # 2 - jqGrid - 358 horquillas; # 3 - Flexigrid - 238; # 4 - Tablas de datos - 216; # 5 - Ingrid - 41; # 6 - jqGridView - 0;
ljs.dev

1
Eche un vistazo a nexts.github.io/Clusterize.js
Denis

¿Puedo comentar que Slickgrid todavía está vivo y bien, pero el repositorio de mleibman mencionado anteriormente está muerto? Nuevo enlace: github.com/6pac/SlickGrid (mleibman lo menciona en una nota final sobre su repositorio), o www.slickgrid.net
Ben McIntyre

25

No pretendo comenzar una guerra de llamas, pero suponiendo que sus investigadores sean humanos, no los conoce tan bien como cree. El hecho de que tengan petabytes de datos no los hace capaces de ver incluso millones de registros de ninguna manera significativa. Podrían decir que quieren ver millones de discos, pero eso es una tontería. Haga que sus investigadores más inteligentes hagan algunas matemáticas básicas: suponga que pasan 1 segundo viendo cada registro. A ese ritmo, tomará 1000000 segundos, lo que equivale a más de seis semanas (de 40 horas semanales de trabajo sin descansos para la comida o el baño).

¿Ellos (o usted) piensan seriamente que una persona (la que mira la cuadrícula) puede reunir ese tipo de concentración? ¿Realmente están haciendo mucho en ese segundo o están (más probablemente) filtrando las cosas que no quieren? Sospecho que después de ver un subconjunto de "tamaño razonable", podrían describirle un filtro que filtraría automáticamente esos registros.

Como también implicaron paxdiablo y Sleeper Smith y Lasse V Karlsen, usted (y ellos) no han pensado en los requisitos. En el lado positivo, ahora que ha encontrado SlickGrid, estoy seguro de que la necesidad de esos filtros se hizo evidente de inmediato.


2
Tener la necesidad de millones de filas no siempre se trata de verlas. A veces, los clientes desean un volcado parcial de registros para ejecutar en sus propios sistemas de análisis de datos.
cbmeeks

10
Si es un volcado de datos para su propio análisis, entonces no se mostrará en una cuadrícula en una página web, ¿verdad?
Steven Benitez

55
No tengo que verlos todos a la vez. Para eso Ctrl+Festán los ordenamientos de columnas . La alternativa (paginación, búsqueda en el sitio web) es mucho peor. Solo mire StackOverflow cuando intente desplazarse por las preguntas o respuestas, Reddit para desplazarse por el historial de comentarios de un usuario. La clasificación y la búsqueda instantánea proporcionan el poder que tiene Windows Explorer, pero carecen de sitios web.
Ian Boyd

15

Puedo decir con bastante certeza que realmente no es necesario mostrar millones de filas de datos al usuario.

No hay ningún usuario en el mundo que pueda comprender o administrar ese conjunto de datos, por lo que incluso si técnicamente logras llevarlo a cabo, no resolverás ningún problema conocido para ese usuario.

En cambio, me enfocaría en por qué el usuario quiere ver los datos. El usuario no quiere ver los datos solo para ver los datos, por lo general, se hace una pregunta. Si te enfocas en responder esas preguntas, entonces estarías mucho más cerca de algo que resuelva un problema real.


16
Mis usuarios son investigadores que están acostumbrados a petabytes de datos. Creo que conozco a mis usuarios un poco mejor que tú, aunque ciertamente tienes razón en el caso general. En cuanto al por qué , esta cuadrícula de datos es simplemente parte de un conjunto de herramientas para administrar big data.
Rudiger

7

Recomiendo Ext JS Grid con la función Vista en búfer.

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


ExtJs, de hecho. Básicamente está construido especialmente para la presentación de datos
KdgDev

1
ExtJs es tan bueno que quiero llorar que no está construido sobre jQuery
James Westgate

Ahora puede cargar solo las partes de ExtJS relacionadas con la cuadrícula, de modo que agregar una cuadrícula ExtJS a su aplicación no sea demasiado pesado. Sin embargo, aún debe considerar las diferencias en apariencia y usar la forma ExtJS de temática para ese componente.
JD Smith

7

(Descargo de responsabilidad: soy el autor de w2ui)

Recientemente escribí un artículo sobre cómo implementar la cuadrícula de JavaScript con 1 millón de registros ( http://w2ui.com/web/blog/7/JavaScript-Grid-with-One-Million-Records ). Descubrí que, en última instancia, hay 3 restricciones que evitan que se tome más alto:

  1. La altura del div tiene un límite (se puede superar mediante desplazamiento virtual)
  2. Operaciones como ordenar y buscar comienzan a ser lentas después de aproximadamente 1 millón de registros
  3. RAM es limitada porque los datos se almacenan en una matriz de JavaScript

He probado la cuadrícula con 1 millón de registros (excepto IE) y funciona bien. Vea el artículo para demostraciones y ejemplos.


Con este millón de registros, su página html tiene un tamaño de 3 MB, pero cuando cargo mis datos, la página tiene 15 MB, ¿w2ui puede manejar eso? Necesito todos los datos para algunos cálculos.
Chetan S. Choudhary

6

dojox.grid.DataGrid ofrece una abstracción JS para datos para que pueda conectarla a varios backends con las tiendas dojo.data proporcionadas o escribir la suya propia. Obviamente, necesitará uno que admita acceso aleatorio para tantos registros. DataGrid también proporciona accesibilidad completa.

Edite, así que aquí hay un enlace al artículo de Matthew Russell que debería proporcionar el ejemplo que necesita, viendo millones de registros con dojox.grid. Tenga en cuenta que usa la versión anterior de la cuadrícula, pero los conceptos son los mismos, solo hubo algunas mejoras incompatibles de API.

Ah, y es de código abierto totalmente gratuito.



4

Aquí hay un par de optimizaciones que puede aplicar para acelerar las cosas. Solo pensando en voz alta.

Dado que el número de filas puede ser de millones, querrá un sistema de almacenamiento en caché solo para los datos JSON del servidor. No puedo imaginar a nadie que quiera descargar todos los X millones de elementos, pero si lo hicieran, sería un problema. Esta pequeña prueba en Chrome para una matriz en enteros de 20M + se bloquea constantemente en mi máquina.

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

Podría usar LRU o algún otro algoritmo de almacenamiento en caché y tener un límite superior sobre la cantidad de datos que está dispuesto a almacenar en caché.

Para las celdas de la tabla en sí, creo que construir / destruir nodos DOM puede ser costoso. En su lugar, podría predefinir X número de celdas, y cada vez que el usuario se desplace a una nueva posición, inyecte los datos JSON en estas celdas. La barra de desplazamiento prácticamente no tendría relación directa con la cantidad de espacio (altura) que se requiere para representar todo el conjunto de datos. Puede establecer arbitrariamente la altura del contenedor de la tabla, digamos 5000 px, y asignarla al número total de filas. Por ejemplo, si la altura de los contenedores es de 5000 px y hay un total de 10M filas, entonces el starting row ≈ (scroll.top/5000) * 10Mlugar scroll.toprepresenta la distancia de desplazamiento desde la parte superior del contenedor. Pequeña demostración aquí .

Para detectar cuándo solicitar más datos, idealmente un objeto debe actuar como un mediador que escucha los eventos de desplazamiento. Este objeto realiza un seguimiento de qué tan rápido se está desplazando el usuario, y cuando parece que el usuario se está desacelerando o se ha detenido por completo, realiza una solicitud de datos para las filas correspondientes. Recuperar datos de esta manera significa que sus datos estarán fragmentados, por lo que el caché debe diseñarse teniendo esto en cuenta.

También los límites del navegador en las conexiones salientes máximas pueden jugar un papel importante. Un usuario puede desplazarse a una determinada posición que disparará una solicitud AJAX, pero antes de que finalice, el usuario puede desplazarse a otra parte. Si el servidor no responde lo suficiente, las solicitudes se pondrán en cola y la aplicación no responderá. Puede usar un administrador de solicitudes a través del cual se enrutan todas las solicitudes, y puede cancelar las solicitudes pendientes para hacer espacio.


4

Sé que es una pregunta antigua, pero aún así ... También hay dhtmlxGrid que puede manejar millones de filas. Hay una demostración con 50,000 filas, pero el número de filas que se pueden cargar / procesar en la cuadrícula es ilimitado.

Descargo de responsabilidad: soy del equipo DHTMLX.


Quiero mostrar datos Json de 10 MB y quiero usarlos en el cálculo, ¿puedo hacer eso DHTMLX? Con esos datos y etiquetas html, la página de mi navegador es de alrededor de 15 MB. ¿Vale la pena usar DHTMLX?
Chetan S. Choudhary


3

Descargo de responsabilidad: uso mucho YUI DataTable sin dolor de cabeza durante mucho tiempo . Es poderoso y estable. Para sus necesidades, puede utilizar un ScrollingDataTable suports wich

  • desplazamiento x
  • desplazamiento en y
  • desplazamiento xy
  • Un poderoso mecanismo de eventos

Para lo que necesitas, creo que lo que quieres es un tableScrollEvent . Su API dice

Se dispara cuando un DataTable de desplazamiento fijo tiene un desplazamiento.

Como cada DataTable usa un DataSource, puede monitorear sus datos a través de tableScrollEvent junto con el tamaño del bucle de renderizado para completar su ScrollingDataTable de acuerdo con sus necesidades.

El tamaño del bucle de procesamiento dice

En los casos en que su DataTable necesita mostrar la totalidad de un conjunto de datos muy grande, la configuración de renderLoopSize puede ayudar a administrar la representación del DOM del navegador para que el hilo de la interfaz de usuario no se bloquee en tablas muy grandes . Cualquier valor mayor que 0 hará que la representación DOM se ejecute en cadenas setTimeout () que representen el número especificado de filas en cada bucle. El valor ideal debe determinarse por implementación ya que no existen reglas estrictas y rápidas, solo pautas generales:

  • De forma predeterminada, renderLoopSize es 0, por lo que todas las filas se representan en un solo bucle. Un renderLoopSize> 0 agrega gastos generales, así que úsalo cuidadosamente.
  • Si su conjunto de datos es lo suficientemente grande (número de filas X número de columnas X complejidad del formato) que los usuarios experimentan latencia en el renderizado visual y / o hace que el script se cuelgue, considere configurar un renderLoopSize .
  • Un renderLoopSize por debajo de 50 probablemente no valga la pena. Un renderLoopSize> 100 es probablemente mejor.
  • Un conjunto de datos probablemente no se considere lo suficientemente grande a menos que tenga cientos y cientos de filas.
  • Tener un renderLoopSize> 0 y <total de filas hace que la tabla se represente en un bucle (igual que renderLoopSize = 0) pero también desencadena funcionalidades como el trazado de filas de post-renderizado para que se maneje desde un hilo setTimeout separado.

Por ejemplo

// 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> es solo un único DataSource . Puede ser un JSON, JSFunction, XML e incluso un solo elemento HTML

Aquí puedes ver un tutorial simple, provisto por mí. Tenga en cuenta que ningún otro plugin DATA_TABLE admite clics simples y dobles al mismo tiempo. YUI DataTable te permite. Y más, puedes usarlo incluso con JQuery sin dolor de cabeza

Algunos ejemplos, puedes ver

Siéntase libre de preguntar sobre cualquier otra cosa que desee sobre YUI DataTable.

Saludos,


3

De alguna manera no veo el punto, para jqGrid puedes usar la funcionalidad de desplazamiento virtual:

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

pero, de nuevo, se pueden hacer millones de filas con filtrado:

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

Sin embargo, realmente no veo el punto de "como si no hubiera páginas", quiero decir ... no hay forma de mostrar 1,000,000 de filas a la vez en el navegador - esto es 10MB de HTML sin procesar, no veo por qué los usuarios no querrían ver las páginas.

De todas formas...


2

El mejor enfoque que se me ocurre es cargar la porción de datos en formato json para cada desplazamiento o algún límite antes de que finalice el desplazamiento. json se puede convertir fácilmente en objetos y, por lo tanto, las filas de la tabla se pueden construir fácilmente de manera discreta


Así es como lo tengo. Se realiza una solicitud para un conjunto de filas devueltas en JSON ... ¡Estoy buscando un renderizador del lado del cliente javascript que lo admita!
Rudiger

¿¿¿Qué??? ¿Qué diablos es el "renderizador del sitio del cliente"? Cualquier javascript todavía necesitará hacer una llamada ajax, por lo que aún tendrá que conformarse con algún formato de transporte. No puedes escapar haciendo algo de trabajo. Nadie hará esto por ti, mi amigo.
Andriy Drozdyuk

1
Sé que hay que hacer una llamada AJAX; Esta parte es simple. El cliente solicita algo como "start = 20 & limit = 20" y recupera las filas 20-39 del servidor (formato XML o JSON). El "renderizador del lado del cliente" (¡mi terminología!) Realiza estas solicitudes de forma inteligente (por ejemplo, cuando el usuario se desplaza hacia abajo) y presenta los resultados sin problemas en una cuadrícula bonita. Al contrario de lo que dices, alguien más ha hecho este trabajo por mí. Eso es lo que todas las otras respuestas a esta pregunta son.
Rudiger

Bueno, parece que nadie más lo ha hecho por ti :)
Andriy Drozdyuk

1

Recomiendo encarecidamente Open rico . Es difícil de implementar al principio, pero una vez que lo agarres, nunca mirarás hacia atrás.




0

Echa un vistazo a dGrid:

https://dgrid.io/

Estoy de acuerdo en que los usuarios NUNCA, NUNCA necesitarán ver millones de filas de datos a la vez, pero dGrid puede mostrarlos rápidamente (una pantalla a la vez).

No hiervas el océano para hacer una taza de té.


su taza de té (enlace) no se encuentra. :)
Akshay

Tiene su propio sitio ahora :)
ColemanTO
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.