JS grid performance comparison

5.7k views Asked by At

I was using angular-ui-grid (http://ui-grid.info/) to display tabular data. On the whole, it was quite slow and so we decided to use ag-grid (https://www.ag-grid.com/). This was much more performant and better to deal with for regular-sized data-sets.

However, now we are working with some tabular data of the size of 100 cols x 10,000 rows (~1M cells) and the grid seems quite slow in performance.

I was wondering if anyone had used hypergrid (https://fin-hypergrid.github.io/core/2.0.2/) -- it seems to 'solve' the issue of large cols x large rows and in their demo it seems much faster (almost by an order of magnitude) on large data sets.

How does hypergrid compare to ag-grid or react-virtualized in performance on large data sizes?

4

There are 4 answers

10
masterpreenz On BEST ANSWER

I haven't tried any of those example libraries you mentioned, but perhaps I could explain why fin-hypergrid stands out the most. My opinion is primarily based on my JavaScript knowledge and how this kind of stuff works in the back.

I should probably start with react-virtualized and ag-grid:

  • Both use the way of populating the DOM and only displaying a portion of data to the view, dynamically removing things from the DOM that aren't visible anymore and adding the upcoming things in advance. Now the problem here lies in adding and removing things in the DOM since this tends to be executed really fast / multiple times a second. Because of this we experience some lag or jitter. You can actually check Web Console > Profiles > Record JavaScript CPU Profiles and see that this method takes time to complete. So the only thing that differs from react-virtualized and ag-grid are their algorithms of applying these changes in the smoothest possible manner.

ag-grid, from what I can see, is the one that suffers the most from this issue as you could actually see some elements that haven't finished rendering yet and experience severe lag when you scroll too fast.

react-virtualized on the other hand does a splendid job implementing its algorithm in the smoothest possible manner. This might be the best library available in the DOM manipulation category though it still suffers from the problem of manipulating the DOM too fast which creates lag, though this is only seen when large chunks of data are involved.

Here are the reasons why fin-hypergrid excels:

  • The best asset of fin-hypergrid is it doesn't perform DOM manipulation at all so you are already saved from the problem caused by adding and removing things too fast since it uses <canvas>
  • fin-hypergrid also displays only data that the user sees and dynamically removes things that aren't visible. It also adds in advance to achieve a smooth scroll feeling, so no still-rendering items are shown.
  • fin-hypergrid also does a really great job on their scrolling algorithm to attain the smoothest possible manner, so there is no jitter or lag.

Now that doesn't mean that hypergrid is all good, it has some disadvantages too:

  • Since fin-hypergrid is made with HTML5 Canvas, styling it will become a real pain as it doesn't accept CSS. You would need to style it manually.
  • A few things to keep in mind are form controls such as <select>, radio buttons, checkboxes, etc. would be a real pain to implement. If you are trying to implement something like this then proceed with caution.
  • It's primarily used for displaying data with simple column edits, not involving anything other than a textbox, and achieving the most smooth scroll feeling.

Now in conclusion, I would probably suggest using react-virtualized instead since it offers the smoothest scroll, above fin-hypergrid. If you are willing to disregard the downsides of fin-hypergrid, then fin-hypergrid is the best option.

UPDATED:

Since we discussed JS / CSS, canvas implementations of these tables. I should have mentioned the last possible contender though this one is not primarily a js table library but a framework in which Google Sheets might have been used it is called d3.js.

  • d3.js has the speed and power of canvas and at the same time retains HTML structure, this means that it is possible to style it with CSS!
  • It maximizes the usage of HTML 5 SVG
  • I can't say anything more better in d3.js

The only downsides of d3.js in this discussion is that:

  • There is no available good table libraries out there that uses d3.js. Google Sheets that is. But they do not share code.
  • d3.js is just very hard to learn, though there are lots of stuff out there that helps us learn this faster but not that fast.

If you wanted speed of Canvas with CSS styling capabalities then d3.js is the key the problem is learning it.

2
egorlitvinenko On

I used free version of handsontable for big datasets. See example with 10000*100 cells - http://jsfiddle.net/handsoncode/Lp4qn55v/

For example, for angular 1.5:

<hot-table class="hot handsontable htRowHeaders htColumnHeaders" settings="settings"
                       row-headers="rowHeaders"  datarows="dba">
    <hot-column ng-repeat="column in Value" data="{{column.COL1}}" >
    </hot-column>
</hot-table>

See documentation here

3
fjoe On

Have you considered using something designed for large data sets?

Clusterize.js

I believe the way it works is it only loads the elements data for the ones you are looking at. Therefore the browser doesn't lag because it has the elements need to display the viewport.

The demo page loads 3 examples with 500,000 elements each (1,500,000 total elements).

Update - With Example Snippet

  • Because I do not have 100,000 x 200 elements of data to load I build 100 x 200 using JavaScript.
  • Then I copy that array and insert it into the data array 1000 times.
  • This way I can reach your total data set size without overloading the JavaScript engine.
  • Since it is hard to tell that it is really doing 100,000 rows I called the getRowsAmount() function which is displayed at the top of the output.
  • You may need to play with the block & cluster sizes based on your viewport but this should show you that this library is totally possible of supporting your needs.

$(function() {
  var dataBlock = []
  var data = [];
  const rows = 100000
  const cols = 200;
  const blockSize = 100;
  const blocks = rows / blockSize;

  for (let i = 0; i < cols; i++) {
    $("thead tr").append(`<th>C${i}</td>`);
  }

  for (let j = 0; j < blockSize ; j++) {
    var tr = $("<tr />");
    for (var i = 0; i < cols; i++) {
      tr.append(`<td>R${j}-C${i}</td>`);
    }

    dataBlock.push($("<div />").append(tr).html());
  }

  for (let i = 0; i < blocks; i++) {
    $.merge(data, dataBlock);
  }

  var clusterize = new Clusterize({
    rows: data,
    scrollId: 'scrollArea',
    contentId: 'contentArea',
    rows_in_block: 10,
    blocks_in_cluster: 2,
  });
  
  $("#totalRows").text(clusterize.getRowsAmount());
});
table td {
  white-space: nowrap;
  padding: 0 5px;
}
<html>

<head>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
  <link href="https://clusterize.js.org/css/clusterize.css" rel="stylesheet" />

  <script src="https://clusterize.js.org/js/clusterize.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>

<body>
  Total Rows: <span id="totalRows"></span>
  <div class="clusterize">
    <div id="scrollArea" class="clusterize-scroll">
      <table class="table">
        <thead>
          <tr></tr>
        </thead>
        <tbody id="contentArea" class="clusterize-content">
          <tr class="clusterize-no-data">
            <td>Loading data…</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</body>

</html>

The library supports appending data so with your large data sets your may want to load some of your data through AJAX.

4
ymssa___ On

I have gone through different data grid options. Then I found this.

Hope this answer helps to anyone who is looking for performance comparison between data grids.

Few points to be noted here, even you have gone through with the article I provided.

1 - Once a grid is 'fast enough', which means the rendering lag is not noticeable, then it doesn't matter which grid is faster than the next.

2 - A canvas based grid is not a HTML grid - you cannot customise it with HTML. The grid will struggle to be styled / themed / customised by the standard JavaScript / CSS developer.

Pick your poison because it is not just the performance when it comes to the consumer level.