JS网格性能对比
JS grid performance comparison
我正在使用 angular-ui-网格 (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/)。这对于处理常规大小的数据集来说性能更高,也更好。
但是,现在我们正在处理一些大小为 100 列 x 10,000 行(约 100 万个单元格)的表格数据,并且网格的性能似乎 quite 很慢。
我想知道是否有人使用过 hypergrid (https://fin-hypergrid.github.io/core/2.0.2/) -- 似乎 'solve' 大列 x 大行的问题在他们的演示中似乎快得多(几乎是数量级)在大型数据集上。
hypergrid compare to ag-grid or react-virtualized 在大数据量上的表现如何?
我没有尝试过您提到的任何示例库,但也许我可以解释为什么 fin-hypergrid
最突出。我的意见主要基于我的 JavaScript 知识以及这类东西在后台的工作原理。
我应该从 react-virtualized
和 ag-grid
:
开始
- 两者都使用填充 DOM 的方式,只在视图中显示一部分数据,动态地从 DOM 中删除不再可见的内容,并将即将到来的内容添加到进步。现在这里的问题在于在 DOM 中添加和删除内容,因为这往往执行得非常快/每秒多次。因此,我们会遇到一些滞后或抖动。您实际上可以检查 Web 控制台 > 配置文件 > 记录 JavaScript CPU 配置文件 并查看此方法需要时间才能完成。因此,与
react-virtualized
和 ag-grid
唯一不同的是它们以最平滑的方式应用这些更改的算法。
ag-grid
,据我所知,是受此问题影响最大的一个,因为您实际上可以看到一些尚未完成渲染的元素,并且当您滚动得太快时会遇到严重的延迟.
另一方面,react-virtualized
在以最流畅的方式实施其算法方面做得非常出色。这可能是 DOM 操作类别中可用的最佳库,尽管它仍然存在操作 DOM 速度过快导致延迟的问题,尽管这仅在涉及大块数据时才会出现。
以下是 fin-hypergrid
出色的原因:
fin-hypergrid
的最大优点是它根本不执行 DOM 操作,因此您已经避免了由于使用 [=19] 过快添加和删除东西而引起的问题=]
fin-hypergrid
也仅显示用户看到的数据并动态删除不可见的内容。它还提前添加以实现平滑的滚动感,因此不会显示静止渲染的项目。
fin-hypergrid
他们的滚动算法也做得非常好,以获得最平滑的方式,因此没有抖动或滞后。
这并不意味着 hypergrid
就很好,它也有一些缺点:
- 由于
fin-hypergrid
是用 HTML5 Canvas 制作的,因此样式设置将变得非常痛苦,因为它不接受 CSS。您需要手动设置样式。
- 需要记住的几件事是表单控件,例如
<select>
、单选按钮、复选框等,实施起来真的很痛苦。如果您正在尝试实施类似的操作,请谨慎行事。
- 主要用于显示数据,简单的列编辑,不涉及文本框以外的任何内容,实现最流畅的滚动感。
现在总而言之,我可能会建议使用 react-virtualized
,因为它提供了比 fin-hypergrid
更流畅的滚动。如果你愿意忽略fin-hypergrid
的缺点,那么fin-hypergrid
是最好的选择。
更新:
自从我们讨论了 JS / CSS、canvas 这些 table 的实现。我应该提到最后一个可能的竞争者,尽管这个主要不是 js table 库,而是一个可能使用了 Google Sheets
的框架,它被称为 d3.js.
d3.js
拥有canvas的速度和威力,同时保留了HTML的结构,也就是说可以用CSS来设计风格!
- 它最大限度地利用了HTML 5 SVG
- 我在
d3.js
中说得再好不过了
在此讨论中 d3.js
的唯一缺点是:
- 没有可用的好 table 库使用
d3.js
。 Google Sheets
即。但是他们不共享代码。
d3.js
很难学,尽管有很多东西可以帮助我们更快但不是那么快地学习。
如果您想要 Canvas 的速度和 CSS 样式功能,那么 d3.js
是学习它的关键问题。
我使用免费版的 handsontable 来处理大数据集。
请参阅包含 10000*100 个单元格的示例 - http://jsfiddle.net/handsoncode/Lp4qn55v/
例如,对于 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>
查看文档 here
您是否考虑过使用为大型数据集设计的东西?
我相信它的工作方式是它只加载您正在查看的元素数据。因此浏览器不会滞后,因为它具有显示视口所需的元素。
演示页面加载了 3 个示例,每个示例包含 500,000 个元素(总共 1,500,000 个元素)。
更新 - 带有示例代码段
- 因为我没有要加载的 100,000 x 200 数据元素,所以我使用 JavaScript.
构建了 100 x 200
- 然后我复制那个数组并将其插入数据数组 1000 次。
- 这样我就可以在不使 JavaScript 引擎过载的情况下达到您的总数据集大小。
- 因为很难判断它是否真的执行了 100,000 行,所以我调用了显示在输出顶部的
getRowsAmount()
函数。
- 您可能需要根据您的视口调整块大小和簇大小,但这应该表明该库完全有可能满足您的需求。
$(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.
我浏览了不同的数据网格选项。然后我找到了this.
希望此回答对正在寻找数据网格之间的性能比较的任何人有所帮助。
这里有几点需要注意,即使你看过我提供的文章。
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.
选择你的毒药,因为当涉及到消费者层面时,这不仅仅是性能。
我正在使用 angular-ui-网格 (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/)。这对于处理常规大小的数据集来说性能更高,也更好。
但是,现在我们正在处理一些大小为 100 列 x 10,000 行(约 100 万个单元格)的表格数据,并且网格的性能似乎 quite 很慢。
我想知道是否有人使用过 hypergrid (https://fin-hypergrid.github.io/core/2.0.2/) -- 似乎 'solve' 大列 x 大行的问题在他们的演示中似乎快得多(几乎是数量级)在大型数据集上。
hypergrid compare to ag-grid or react-virtualized 在大数据量上的表现如何?
我没有尝试过您提到的任何示例库,但也许我可以解释为什么 fin-hypergrid
最突出。我的意见主要基于我的 JavaScript 知识以及这类东西在后台的工作原理。
我应该从 react-virtualized
和 ag-grid
:
- 两者都使用填充 DOM 的方式,只在视图中显示一部分数据,动态地从 DOM 中删除不再可见的内容,并将即将到来的内容添加到进步。现在这里的问题在于在 DOM 中添加和删除内容,因为这往往执行得非常快/每秒多次。因此,我们会遇到一些滞后或抖动。您实际上可以检查 Web 控制台 > 配置文件 > 记录 JavaScript CPU 配置文件 并查看此方法需要时间才能完成。因此,与
react-virtualized
和ag-grid
唯一不同的是它们以最平滑的方式应用这些更改的算法。
ag-grid
,据我所知,是受此问题影响最大的一个,因为您实际上可以看到一些尚未完成渲染的元素,并且当您滚动得太快时会遇到严重的延迟.
react-virtualized
在以最流畅的方式实施其算法方面做得非常出色。这可能是 DOM 操作类别中可用的最佳库,尽管它仍然存在操作 DOM 速度过快导致延迟的问题,尽管这仅在涉及大块数据时才会出现。
以下是 fin-hypergrid
出色的原因:
fin-hypergrid
的最大优点是它根本不执行 DOM 操作,因此您已经避免了由于使用 [=19] 过快添加和删除东西而引起的问题=]fin-hypergrid
也仅显示用户看到的数据并动态删除不可见的内容。它还提前添加以实现平滑的滚动感,因此不会显示静止渲染的项目。fin-hypergrid
他们的滚动算法也做得非常好,以获得最平滑的方式,因此没有抖动或滞后。
这并不意味着 hypergrid
就很好,它也有一些缺点:
- 由于
fin-hypergrid
是用 HTML5 Canvas 制作的,因此样式设置将变得非常痛苦,因为它不接受 CSS。您需要手动设置样式。 - 需要记住的几件事是表单控件,例如
<select>
、单选按钮、复选框等,实施起来真的很痛苦。如果您正在尝试实施类似的操作,请谨慎行事。 - 主要用于显示数据,简单的列编辑,不涉及文本框以外的任何内容,实现最流畅的滚动感。
现在总而言之,我可能会建议使用 react-virtualized
,因为它提供了比 fin-hypergrid
更流畅的滚动。如果你愿意忽略fin-hypergrid
的缺点,那么fin-hypergrid
是最好的选择。
更新:
自从我们讨论了 JS / CSS、canvas 这些 table 的实现。我应该提到最后一个可能的竞争者,尽管这个主要不是 js table 库,而是一个可能使用了 Google Sheets
的框架,它被称为 d3.js.
d3.js
拥有canvas的速度和威力,同时保留了HTML的结构,也就是说可以用CSS来设计风格!- 它最大限度地利用了HTML 5 SVG
- 我在
d3.js
中说得再好不过了
在此讨论中 d3.js
的唯一缺点是:
- 没有可用的好 table 库使用
d3.js
。Google Sheets
即。但是他们不共享代码。 d3.js
很难学,尽管有很多东西可以帮助我们更快但不是那么快地学习。
如果您想要 Canvas 的速度和 CSS 样式功能,那么 d3.js
是学习它的关键问题。
我使用免费版的 handsontable 来处理大数据集。 请参阅包含 10000*100 个单元格的示例 - http://jsfiddle.net/handsoncode/Lp4qn55v/
例如,对于 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>
查看文档 here
您是否考虑过使用为大型数据集设计的东西?
我相信它的工作方式是它只加载您正在查看的元素数据。因此浏览器不会滞后,因为它具有显示视口所需的元素。
演示页面加载了 3 个示例,每个示例包含 500,000 个元素(总共 1,500,000 个元素)。
更新 - 带有示例代码段
- 因为我没有要加载的 100,000 x 200 数据元素,所以我使用 JavaScript. 构建了 100 x 200
- 然后我复制那个数组并将其插入数据数组 1000 次。
- 这样我就可以在不使 JavaScript 引擎过载的情况下达到您的总数据集大小。
- 因为很难判断它是否真的执行了 100,000 行,所以我调用了显示在输出顶部的
getRowsAmount()
函数。 - 您可能需要根据您的视口调整块大小和簇大小,但这应该表明该库完全有可能满足您的需求。
$(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.
我浏览了不同的数据网格选项。然后我找到了this.
希望此回答对正在寻找数据网格之间的性能比较的任何人有所帮助。
这里有几点需要注意,即使你看过我提供的文章。
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.
选择你的毒药,因为当涉及到消费者层面时,这不仅仅是性能。