226

I need to present a large number of rows of data (ie. millions of rows) to the user in a grid using JavaScript.

The user shouldn't see pages or view only finite amounts of data at a time.

Rather, it should appear that all of the data are available.

Instead of downloading the data all at once, small chunks are downloaded as the user comes to them (ie. by scrolling through the grid).

The rows will not be edited through this front end, so read-only grids are acceptable.

What data grids, written in JavaScript, exist for this kind of seamless paging?

Rudiger
  • 6,634
  • 9
  • 40
  • 57
  • 1
    I unaccepted the jqgrid answer, since it seems to fail for large data sets... Any other suggestions? What about http://www.ext-livegrid.com? – Rudiger Mar 10 '10 at 16:06
  • I implemented ext-livegrid, and that fails for large data sets (ie. more than 50,000 rows) too.. Any robust implementations of this, or should I go with Adobe Flex (which I know can do it)? – Rudiger Mar 13 '10 at 22:55
  • @Rudiger are you looking for existing grid implementations only or optimization techniques as well? – Anurag Mar 13 '10 at 23:17
  • `@Anurag` I'd like to hear techniques for rendering the grid on the client-side (eg. determining row-number from scroll-bar position, preventing scroll-bar nub from disappearing for large number of rows, when to make requests for data, etc). Optimization of the server-side isn't really necessary; it's pretty simple (and fast) to give the client a set of rows when he asks for it. – Rudiger Mar 13 '10 at 23:24
  • @Rudiger - (about jqGrid) it fails even when when loading rows on an as-needed basis? See http://www.trirand.com/blog/jqgrid/jqgrid.html -> New in version 3.6 -> True scrolling Rows – Greg Mar 14 '10 at 04:10
  • 1
    `@Greg:` I know these things can be _very_ browser-specific (YBMV), but in my case, the 500,000+ row demos are either 1) failing to show the scroll-bar or 2) showing up to some number of rows (ie 51,900)... You can check out a demo (http://www.trirand.com/blog/phpjqgrid/examples/paging/scrollbar/default.php), and there's lots written about the feature in the forums (http://www.google.com/search?hl=en&q=site%3Atrirand.com+trirand+forum+%22true+scrolling%22) To me, True Scrolling Rows looks like a new feature that has some bugs that need to be worked out. – Rudiger Mar 14 '10 at 05:07
  • At first you want your data to be downloaded in chunks, then when presented with ajax solution with json objects, you reject it. Make up your mind as to what your question is. – Andriy Drozdyuk Mar 16 '10 at 15:18
  • 1
    `@drozzy:` I haven't "rejected" anything. All the solutions, including "write your own" solutions, will be AJAX. The question is: which data grids exist that support seamless scrolling for millions of rows. – Rudiger Mar 16 '10 at 17:20
  • 7
    Write your own. I am sure that the other ones are choking up because they just keep appending to the DOM. I think you will need a solution that *removes* rows as they scroll *off* the screen. That is the only way. You simply can't have a million table rows in the DOM and expect every browser to to display and scroll seamlessly in every environment. Be reasonable. – Josh Stodola Mar 18 '10 at 00:35
  • `@Josh Stodola:` Exactly. I had assumed that the existing grids were designed to handle millions of rows precisely the way you describe it (a "fixed" window of rows from a large table). – Rudiger Mar 18 '10 at 01:36
  • 2
    @Rudiger: SlickGrid now supports unlimited numbers of rows natively. See http://github.com/mleibman/SlickGrid/tree/unlimited-rows . Once this gets tested thoroughly it will be merged into the main branch. – Tin Jun 28 '10 at 06:06
  • 1
    ""I need to present millions of rows of data to users" - no, you really don't. Trust me. Your users will track you down, beat you to death, burn your corpse then spit on your charred remains :-)" Quoted again for the sake of it. That post didnt' get 10 up votes for nothing. – Sleeper Smith Mar 18 '11 at 06:30
  • 11
    And I feel sorry which ever firm you are working for. For your information, a 1920x1080 screen with only 1 million rows displayed, will jump *20 row* for every one pixel of movement on the scroll bar. Go do some usability testing instead of wasting your time. – Sleeper Smith Mar 18 '11 at 06:34
  • Rudiger - did you also happen to try a lot columns instead of just rows? Do you have a solution for virtualizing columns? – oneiros Feb 27 '12 at 05:31
  • 1
    I think virtualizing the rows is the right idea. Why not keep track of where they are scrolled to and making sure that you load in [three] screens above their current position and [three] screens below their current position? The rest of the space would be filled up with a big rectangle sized to make it look right. Much easier on the browser--should perform better. But to the end user, they should never be able to tell the difference. Browser 'find' functionality wouldn't work though. – SimplGy Mar 21 '12 at 15:23
  • http://nexts.github.io/Clusterize.js/ – Chris S Jul 13 '15 at 18:21
  • 3
    This question and its top two answers (at least) are exceedingly useful. It might have attracted some low-quality answers, but by no means should this question be Closed. Using SlickGrid to solve this problem can save people many many hours of trouble and difficult coding, if they attempt to reimplement this for themselves. – Sam Watkins Apr 11 '16 at 00:58
  • @casperOne I don't understand at all why you voted to close this question as opinion-based. This is a practical, non-opinionated question which will only have a couple realistic answers. It's well-focused, and deserves to be re-eopend so we can get some modern standards-based answers for it. – Brad Apr 08 '19 at 02:23
  • https://jsgrids.io/ has a list of grid libraries. You can filter by whether they support virtualization for large data sets. – a paid nerd Jul 14 '20 at 00:37

19 Answers19

192

(Disclaimer: I am the author of SlickGrid)

UPDATE This has now been implemented in SlickGrid.

Please see http://github.com/mleibman/SlickGrid/issues#issue/22 for an ongoing discussion on making SlickGrid work with larger numbers of rows.

The problem is that SlickGrid does not virtualize the scrollbar itself - the scrollable area's height is set to the total height of all the rows. The rows are still being added and removed as the user is scrolling, but the scrolling itself is done by the browser. That allows it to be very fast yet smooth (onscroll events are notoriously slow). The caveat is that there are bugs/limits in the browsers' CSS engines that limit the potential height of an element. For IE, that happens to be 0x123456 or 1193046 pixels. For other browsers it is higher.

There is an experimental workaround in the "largenum-fix" branch that raises that limit significantly by populating the scrollable area with "pages" set to 1M pixels height and then using relative positioning within those pages. Since the height limit in the CSS engine seems to be different and significantly lower than in the actual layout engine, this gives us a much higher upper limit.

I am still looking for a way to get to unlimited number of rows without giving up the performance edge that SlickGrid currently holds over other implementations.

Rudiger, can you elaborate on how you solved this?

Rudiger
  • 6,634
  • 9
  • 40
  • 57
Tin
  • 9,082
  • 2
  • 34
  • 32
  • 1
    I have found SlickGrid to be the most appealing - especially if one works with jQuery. Congrats! (esp. for the great attitude and persistence.) :-) – Andras Vass Jul 26 '10 at 10:41
  • I am trying to use slickgrid to show excel headers, and I am seeing that when having too many columns slickgrid only optimizes the scrolling of rows and not of columns. I have also noticed that when having more than 120 columns or so - slickgrid puts the new rows in a new line. Can the maximum number of rows be set somewhere in the files? – oneiros Feb 25 '12 at 02:19
  • 1
    SlickGrid v2.1 has uses virtual scrolling for columns as well as rows. Also, the overflowing columns issue has been resolved. – Tin Sep 27 '12 at 20:25
  • @Tin - This is similar to my approach; I was years ahead of my time! "A lazy block layout primitive for building infinite scroll into web applications." https://docs.google.com/document/d/1-tbcMJV8wNbX2g5ehNIcE_1W7Kj_B3g9w1BrUgHnh3U/preview?pli=1 – Rudiger Sep 19 '13 at 17:42
  • @Rudiger Yes, I've seen this on Blink group about a month ago, but I'm not quite sure how this fit into the picture. The lazy layout operates on elements actually present in the DOM, which we can't really do. Please elaborate :) – Tin Sep 19 '13 at 18:33
  • @Tin can this grid handles millions of rows with hundreds of columns? I have tried many tools and as soon as the number of columns increase to 100 - 200 their performance hit the limit. Thanks. – NKD Sep 29 '15 at 18:28
85

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

"SlickGrid utilizes virtual rendering to enable you to easily work with hundreds of thousands of items without any drop in performance. In fact, there is no difference in performance between working with a grid with 10 rows versus a 100’000 rows."

Some highlights:

  • Adaptive virtual scrolling (handle hundreds of thousands of rows)
  • Extremely fast rendering speed
  • Background post-rendering for richer cells
  • Configurable & customizable
  • Full keyboard navigation
  • Column resize/reorder/show/hide
  • Column autosizing & force-fit
  • Pluggable cell formatters & editors
  • Support for editing and creating new rows." by mleibman

It's free (MIT license). It uses jQuery.

barbsan
  • 3,418
  • 11
  • 21
  • 28
Andras Vass
  • 11,478
  • 1
  • 37
  • 49
  • It works fine until precisely 131,001 rows... That is, there's a line of code like this: `data.length = Math.min(131000, parseInt(resp.total));` ... And, of course, that hard-coded for a reason :( – Rudiger Mar 18 '10 at 00:00
  • 6
    It took a little work, but I made a few changes to make grid independent of the length of the `data` array. It's a kludge, but I have the responses populating a `bigdata` array, and the smaller `data` pulls from the `bigdata` array. The rest of the program uses the smaller data array, except for the scroll-bar measurement and a few other places that are now unbounded for a large number of rows. All in all, was much easier than writing my own. – Rudiger Mar 18 '10 at 14:41
  • 9
    @Rudiger: SlickGrid now supports unlimited numbers of rows natively. See http://github.com/mleibman/SlickGrid/tree/unlimited-rows . Once this gets tested thoroughly it will be merged into the main branch. – Tin Jun 28 '10 at 06:07
  • I am trying to use slickgrid to show excel headers, and I am seeing that when having too many columns slickgrid only optimizes the scrolling of rows and not of columns. I have also noticed that when having more than 120 columns or so - slickgrid puts the new rows in a new line. Can the maximum number of rows be set somewhere in the files? – oneiros Feb 25 '12 at 02:20
  • if you want something really fast, don't rely on anything that uses jquery to do things in the core, and rather use innerHTML than DOM append. Javascript scrollbars can be noticeable slower than browser scrollbars on slow computers, avoid complex css rules, and you should spend time simplifying the layout of a single row. Micro-optimizations could be significative in this case. This is just general pratices to improve performance. jsPerf.com is your friend. – Vitim.us Nov 10 '12 at 02:22
38

The best Grids in my opinion are below:

My best 3 options are jqGrid, jqxGrid and DataTables. They can work with thousands of rows and support virtualization.

scripto
  • 2,297
  • 1
  • 14
  • 13
  • 1
    +1 for the list, though there's not much in terms of a comparison. A good start would be to add the number of commits for each - 33 for Flexigrid as of now, vs. 491 for SlickGrid. – Dan Dascalescu Nov 08 '12 at 16:13
  • 12
    Screw SO's 5-minute comment edit limit. #1 - jqGrid - [1000+ commits](https://github.com/tonytomov/jqGrid); #2 - [752 for DataTables](https://github.com/DataTables/DataTables); #3 - [491 for SlickGrid](https://github.com/mleibman/SlickGrid); #4 - [33 commits for Flexigrid](https://github.com/paulopmx/Flexigrid). Ingrid - [no update since Jun 2011](http://code.google.com/p/jq-ingrid/source/list). jqGridView - [no update since 2009](http://sourceforge.net/projects/jqgridview/) – Dan Dascalescu Nov 08 '12 at 16:24
  • 3
    Building on the previous comment, I'm including the number of forks per project here: #1 - SlickGrid - 670 forks; #2 - jqGrid - 358 forks; #3 - Flexigrid - 238; #4 - DataTables - 216; #5 - Ingrid - 41; #6 - jqGridView - 0; – ljs.dev May 06 '13 at 06:40
  • 1
    Take a look to http://nexts.github.io/Clusterize.js/ – Denis Jul 30 '15 at 08:12
  • 1
    Can I comment that Slickgrid is still alive and well, but the mleibman repo cited above is dead. New link: http://github.com/6pac/SlickGrid (mleibman references it in a final note on his repo), or www.slickgrid.net – Ben McIntyre Jul 16 '18 at 07:11
  • Adding Smart.Grid https://www.htmlelements.com/demos/grid/overview/ – scripto Jan 26 '22 at 14:45
24

I don't mean to start a flame war, but assuming your researchers are human, you don't know them as well as you think. Just because they have petabytes of data doesn't make them capable of viewing even millions of records in any meaningful way. They might say they want to see millions of records, but that's just silly. Have your smartest researchers do some basic math: Assume they spend 1 second viewing each record. At that rate, it will take 1000000 seconds, which works out to more than six weeks (of 40 hour work-weeks with no breaks for food or lavatory).

Do they (or you) seriously think one person (the one looking at the grid) can muster that kind of concentration? Are they really getting much done in that 1 second, or are they (more likely) filtering out the stuff the don't want? I suspect that after viewing a "reasonably-sized" subset, they could describe a filter to you that would automatically filter out those records.

As paxdiablo and Sleeper Smith and Lasse V Karlsen also implied, you (and they) have not thought through the requirements. On the up side, now that you've found SlickGrid, I'm sure the need for those filters became immediately obvious.

Daniel 'Dang' Griffith
  • 1,641
  • 2
  • 13
  • 13
  • 2
    Having the need for millions of rows isn't always about viewing them. Sometimes clients want a partial dump of records for running in their own data analysis systems. – cbmeeks Oct 30 '12 at 22:05
  • 10
    If its a data dump for their own analysis, then it wouldn't be displayed in a grid on a webpage, would it? – Steven Benitez Feb 04 '13 at 20:34
  • 6
    i don't have to see them all at once. That's what column sorting and `Ctrl+F` are for. The alternative (paging, web-site searching) is **much** worse. Just look at StackOverflow when trying to scroll through questions or answers, Reddit for scrolling through a user's comment history. Sorting and instant searching provide a power that Windows Explorer has, but web-sites lack. – Ian Boyd Jul 10 '14 at 17:57
14

I can say with pretty good certainty that you seriously do not need to show millions of rows of data to the user.

There is no user in the world that will be able to comprehend or manage that data set so even if you technically manage to pull it off, you won't solve any known problem for that user.

Instead I would focus on why the user wants to see the data. The user does not want to see the data just to see the data, there is usually a question being asked. If you focus on answering those questions instead, then you would be much closer to something that solves an actual problem.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • 17
    My users are researchers who are used to *petabytes* of data. I think I know my users a little bit better than you do, though you're certainly right in the general case. As for the *why*, this datagrid is simply part of a set of tools for managing big data. – Rudiger Nov 05 '10 at 15:12
7

(Disclaimer: I am the author of w2ui)

I have recently written an article on how to implement JavaScript grid with 1 million records (http://w2ui.com/web/blog/7/JavaScript-Grid-with-One-Million-Records). I discovered that ultimately there are 3 restrictions that prevent from taking it highter:

  1. Height of the div has a limit (can be overcome by virtual scrolling)
  2. Operations such as sort and search start being slow after 1 million records or so
  3. RAM is limited because data is stored in JavaScript array

I have tested the grid with 1 million records (except IE) and it performs well. See article for demos and examples.

vitmalina
  • 1,829
  • 1
  • 14
  • 7
  • With this one million record your html page is of size 3MB, But when I load my data the page is of 15MB, does w2ui can handle that? I need all data for some calculations. – Chetan S. Choudhary Dec 15 '16 at 12:02
7

I recommend the Ext JS Grid with the Buffered View feature.

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

richardtallent
  • 34,724
  • 14
  • 83
  • 123
  • ExtJs, indeed. It's basically built especially for data presentation – KdgDev Mar 13 '10 at 23:08
  • 1
    ExtJs is so good I want to cry that its not built on top of jQuery – James Westgate Apr 06 '10 at 22:59
  • Now you can load only the grid-related portions of ExtJS, so that adding an ExtJS grid to your application won't be too heavy. However, you still have to consider the differences in appearance and use the ExtJS way of theming for just that component. – JD Smith Jul 11 '12 at 19:19
6

dojox.grid.DataGrid offers a JS abstraction for data so you can hook it up to various backends with provided dojo.data stores or write your own. You'll obviously need one that supports random access for this many records. DataGrid also provides full accessibility.

Edit so here's a link to Matthew Russell's article that should provide the example you need, viewing millions of records with dojox.grid. Note that it uses the old version of the grid, but the concepts are the same, there were just some incompatible API improvements.

Oh, and it's totally free open source.

peller
  • 4,435
  • 19
  • 21
4

I know it's an old question but still.. There is also dhtmlxGrid that can handle millions of rows. There is a demo with 50,000 rows but the number of rows that can be loaded/processed in grid is unlimited.

Disclaimer: I'm from DHTMLX team.

Paul
  • 1,656
  • 11
  • 16
  • I want to show 10 MB Json data and want to use it in calculation, can DHTMLX do that thing, With that data and html tags my browser's page is of around 15 MB. Do it worth using DHTMLX? – Chetan S. Choudhary Dec 15 '16 at 11:58
4

I used jQuery Grid Plugin, it was nice.

Demos

Amr Elgarhy
  • 66,568
  • 69
  • 184
  • 301
  • 2
    Dojo also offers a good grid: http://docs.dojocampus.org/dojox/grid/DataGrid – Select0r Mar 08 '10 at 16:53
  • Sad to see jqgrid not work here... They link to http://stackoverflow.com/questions/tagged/jqgrid from their website http://trirand.net/ – Rudiger Mar 13 '10 at 23:25
4

Here are a couple of optimizations you can apply you speed up things. Just thinking out loud.

Since the number of rows can be in the millions, you will want a caching system just for the JSON data from the server. I can't imagine anybody wanting to download all X million items, but if they did, it would be a problem. This little test on Chrome for an array on 20M+ integers crashes on my machine constantly.

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

You could use LRU or some other caching algorithm and have an upper bound on how much data you're willing to cache.

For the table cells themselves, I think constructing/destroying DOM nodes can be expensive. Instead, you could just pre-define X number of cells, and whenever the user scrolls to a new position, inject the JSON data into these cells. The scrollbar would virtually have no direct relationship to how much space (height) is required to represent the entire dataset. You could arbitrarily set the table container's height, say 5000px, and map that to the total number of rows. For example, if the containers height is 5000px and there are a total of 10M rows, then the starting row ≈ (scroll.top/5000) * 10M where scroll.top represents the scroll distance from the top of the container. Small demo here.

To detect when to request more data, ideally an object should act as a mediator that listens to scroll events. This object keeps track of how fast the user is scrolling, and when it looks like the user is slowing down or has completely stopped, makes a data request for the corresponding rows. Retrieving data in this fashion means your data is going to be fragmented, so the cache should be designed with that in mind.

Also the browser limits on maximum outgoing connections can play an important part. A user may scroll to a certain position which will fire an AJAX request, but before that finishes the user can scroll to some other portion. If the server is not responsive enough the requests would get queued up and the application will look unresponsive. You could use a request manager through which all requests are routed, and it can cancel pending requests to make space.

Anurag
  • 140,337
  • 36
  • 221
  • 257
3

Disclaimer: i heavily use YUI DataTable without no headache for a long time. It is powerful and stable. For your needs, you can use a ScrollingDataTable wich suports

  • x-scrolling
  • y-scrolling
  • xy-scrolling
  • A powerful Event mechanism

For what you need, i think you want is a tableScrollEvent. Its API says

Fired when a fixed scrolling DataTable has a scroll.

As each DataTable uses a DataSource, you can monitoring its data through tableScrollEvent along with render loop size in order to populate your ScrollingDataTable according to your needs.

Render loop size says

In cases where your DataTable needs to display the entirety of a very large set of data, the renderLoopSize config can help manage browser DOM rendering so that the UI thread does not get locked up on very large tables. Any value greater than 0 will cause the DOM rendering to be executed in setTimeout() chains that render the specified number of rows in each loop. The ideal value should be determined per implementation since there are no hard and fast rules, only general guidelines:

  • By default renderLoopSize is 0, so all rows are rendered in a single loop. A renderLoopSize > 0 adds overhead so use thoughtfully.
  • If your set of data is large enough (number of rows X number of Columns X formatting complexity) that users experience latency in the visual rendering and/or it causes the script to hang, consider setting a renderLoopSize.
  • A renderLoopSize under 50 probably isn't worth it. A renderLoopSize > 100 is probably better.
  • A data set is probably not considered large enough unless it has hundreds and hundreds of rows.
  • Having a renderLoopSize > 0 and < total rows does cause the table to be rendered in one loop (same as renderLoopSize = 0) but it also triggers functionality such as post-render row striping to be handled from a separate setTimeout thread.

For instance

// 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> is just a single DataSource. It can be a JSON, JSFunction, XML and even a single HTML element

Here you can see a Simple tutorial, provided by me. Be aware no other DATA_TABLE pluglin supports single and dual click at the same time. YUI DataTable allows you. And more, you can use it even with JQuery without no headache

Some examples, you can see

Feel free to question about anything else you want about YUI DataTable.

regards,

Arthur Ronald
  • 33,349
  • 20
  • 110
  • 136
3

I suggest you read this

http://www.sitepen.com/blog/2008/11/21/effective-use-of-jsonreststore-referencing-lazy-loading-and-more/

ant
  • 22,634
  • 36
  • 132
  • 182
3

I kind of fail to see the point, for jqGrid you can use the virtual scrolling functionality:

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

but then again, millions of rows with filtering can be done:

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

I really fail to see the point of "as if there are no pages" though, I mean... there is no way to display 1,000,000 rows at once in the browser - this is 10MB of HTML raw, I kind of fail to see why users would not want to see the pages.

Anyway...

user125775
  • 141
  • 2
2

best approach i could think of is by loading the chunk of data in json format for every scroll or some limit before the scrolling ends. json can be easily converted to objects and hence table rows can be constructed easily unobtrusively

coder
  • 1,069
  • 3
  • 9
  • 18
  • That's how I have it. A request is made for a set of rows sent back in JSON... I'm looking for a javascript client side renderer that supports this! – Rudiger Mar 10 '10 at 16:07
  • What??? What the heck is "client site renderer"? Any javascript will still need to make an ajax call - so you will still need to settle on some transport format. You can't escape doing some work. No-one will do this for you my friend. – Andriy Drozdyuk Mar 16 '10 at 15:19
  • 1
    I know that an AJAX call has to be made; this part is simple. The client requests something like "start=20&limit=20" and retrieves rows 20-39 from the server (XML or JSON format). The "client-side renderer" (my terminology!) makes these requests intelligently (eg. when the user scrolls down), and renders the results seamlessly in a pretty grid. Contrary to what you say, someone else has done this work for me. That's what all the other answers to this question are. – Rudiger Mar 16 '10 at 17:13
  • Well, it seems no one "else" has done it for you:) – Andriy Drozdyuk Mar 18 '10 at 01:24
1

I know this question is a few years old, but jqgrid now supports virtual scrolling:

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

but with pagination disabled

sksallaj
  • 3,872
  • 3
  • 37
  • 58
1

I would highly recommend Open rico. It is difficult to implement in the the beginning, but once you grab it you will never look back.

mosid
  • 1,044
  • 1
  • 9
  • 15
0

Take a look at dGrid:

https://dgrid.io/

I agree that users will NEVER, EVER need to view millions of rows of data all at once, but dGrid can display them quickly (a screenful at a time).

Don't boil the ocean to make a cup of tea.

ColemanTO
  • 839
  • 7
  • 11
0

I suggest sigma grid, sigma grid has embed paging features which could support millions of rows. And also, you may need a remote paging to do it. see the demo http://www.sigmawidgets.com/products/sigma_grid2/demos/example_master_details.html

Bussy
  • 51
  • 1
  • 2