数百万行的JavaScript数据网格

时间:2010-03-08 16:47:24

标签: javascript jquery html5 datagrid slickgrid

我需要使用JavaScript在网格中向用户显示大量数据行(即数百万行)。

用户不应该一次看到页面或只查看有限数量的数据。

相反,应该看起来所有数据都可用。

不是一次性下载所有数据,而是在用户访问它们时下载小块(即通过滚动网格)。

不会通过此前端编辑行,因此可以使用只读网格。

这种无缝分页存在哪些用JavaScript编写的数据网格?

19 个答案:

答案 0 :(得分:190)

免责声明:我是SlickGrid的作者

<强>更新 现在已在SlickGrid

中实施

请参阅http://github.com/mleibman/SlickGrid/issues#issue/22,了解有关使SlickGrid使用更多行的正在进行的讨论。

问题是SlickGrid没有虚拟化滚动条本身 - 可滚动区域的高度设置为所有行的总高度。当用户滚动时,仍然会添加和删除行,但滚动本身是由浏览器完成的。这使得它非常快速而平稳(onscroll事件非常慢)。需要注意的是,浏览器的CSS引擎中存在限制元素潜在高度的错误/限制。对于IE,恰好是0x123456或1193046像素。对于其他浏览器,它更高。

“largenum-fix”分支中有一个实验性的解决方法,通过将“pages”设置为1M像素高度,然后在这些页面中使用相对定位来填充可滚动区域,从而显着提高了该限制。由于CSS引擎中的高度限制似乎与实际布局引擎中的高度限制不同且明显更低,因此这为我们提供了更高的上限。

我仍然在寻找一种方法来获得无限数量的行,而不会放弃SlickGrid目前在其他实现中保留的性能优势。

鲁迪格,你能详细说明你是如何解决这个问题的吗?

答案 1 :(得分:84)

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

SlickGrid利用虚拟渲染,使您能够轻松处理数十万个项目而不会降低性能。事实上,使用10行网格与100行网格之间的性能没有差异。” 000行。

一些亮点:

  • 自适应虚拟滚动(处理数十万行)
  • 极快的渲染速度
  • 更富细胞的后期渲染
  • 可配置&amp;定制
  • 全键盘导航
  • 列调整大小/重新排序/显示/隐藏
  • 柱自动调节&amp;力配合
  • 可插拔单元格格式器&amp;编辑
  • 支持编辑和创建新行。mleibman

它是免费的(麻省理工学院许可证)。 它使用jQuery。

答案 2 :(得分:35)

我认为最好的网格如下:

我最好的3个选项是jqGrid,jqxGrid和DataTables。他们可以使用数千行并支持虚拟化。

答案 3 :(得分:24)

我并不是要开始一场火焰战争,但假设你的研究人员是人类,你就不会像你想象的那样了解它们。仅仅因为他们拥有 PB级数据并不能使他们以任何有意义的方式查看数百万条记录。他们可能会说他们想要看到数百万条记录,但这只是愚蠢的。让你最聪明的研究人员做一些基本的数学运算:假设他们花1秒钟查看每条记录。按照这个速度,它将花费1000000秒,超过六周(40小时工作周,没有食物或盥洗室休息)。

他们(或你)是否认真地认为一个人(看着网格的人)可以集中注意力?他们真的在1秒内完成了很多工作,或者他们(更有可能)过滤掉想要的东西?我怀疑在查看“合理大小”的子集后,他们可以向您描述一个过滤器,它会自动过滤掉那些记录。

正如paxdiablo和Sleeper Smith以及Lasse V Karlsen所暗示的那样,你(和他们)没有考虑过要求。从好的方面来说,既然您已经找到了SlickGrid,我确信这些过滤器的需求立即显而易见。

答案 4 :(得分:15)

我可以非常肯定地说,您真的不需要向用户显示数百万行数据。

世界上没有任何用户能够理解或管理该数据集,因此即使您在技术上设法将其拉下来,也不会为该用户解决任何已知问题。

相反,我会专注于为什么用户想要查看数据。用户不希望看到数据只是为了查看数据,通常会有一个问题。如果你专注于回答那些问题,那么你就会更接近解决实际问题的东西。

答案 5 :(得分:7)

我推荐使用具有缓冲视图功能的Ext JS Grid。

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

答案 6 :(得分:6)

dojox.grid.DataGrid提供了数据的JS抽象,因此您可以将其连接到提供的dojo.data存储的各种后端,也可以编写自己的后端。你显然需要一个支持这么多记录的随机访问。 DataGrid还提供完全可访问性。

编辑所以这里是Matthew Russell's article的链接,应提供您需要的示例,使用dojox.grid查看数百万条记录。请注意,它使用旧版本的网格,但概念是相同的,只有一些不兼容的API改进。

哦,这是完全免费的开源。

答案 7 :(得分:6)

(免责声明:我是w2ui的作者)

我最近写了一篇关于如何实现包含100万条记录(http://w2ui.com/web/blog/7/JavaScript-Grid-with-One-Million-Records)的JavaScript网格的文章。我发现最终有3个限制阻止它更高:

  1. div的高度有一个限制(可以通过虚拟滚动来克服)
  2. 排序和搜索等操作在100万条记录后开始变慢
  3. RAM受限,因为数据存储在JavaScript数组
  4. 我用100万条记录(IE除外)测试了网格,效果很好。有关演示和示例,请参阅文章。

答案 8 :(得分:4)

我使用jQuery Grid Plugin,很不错。

Demos

答案 9 :(得分:4)

您可以通过以下几种优化来加快速度。只是大声思考。

由于行数可以是数百万,因此您只需要一个来自服务器的JSON数据的缓存系统。我无法想象有人想要下载所有X万件物品,但如果他们这样做,那将是一个问题。对于20M +整数的数组,Chrome上的这个little test会不时在我的计算机上崩溃。

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

您可以使用LRU或其他一些缓存算法,并对您愿意缓存的数据数量设置上限。

对于表格单元本身,我认为构建/销毁DOM节点可能很昂贵。相反,您可以预先定义X个单元格,每当用户滚动到新位置时,将JSON数据注入这些单元格。滚动条实际上​​与表示整个数据集所需的空间(高度)没有直接关系。你可以任意设置表容器的高度,比如5000px,并将其映射到总行数。例如,如果容器高度为5000px且总共有10M行,那么starting row ≈ (scroll.top/5000) * 10M其中scroll.top表示距容器顶部的滚动距离。 Small demo here

要检测何时请求更多数据,理想情况下,对象应充当侦听滚动事件的中介。此对象跟踪用户滚动的速度,当用户看起来正在减速或完全停止时,会对相应的行发出数据请求。以这种方式检索数据意味着您的数据将被分割,因此缓存的设计应考虑到这一点。

浏览器对最大传出连接的限制也可以发挥重要作用。用户可以滚动到某个位置,该位置将触发AJAX请求,但在完成之前,用户可以滚动到某个其他部分。如果服务器响应不足,请求将排队,应用程序将看起来没有响应。您可以使用请求管理器来通过所有请求进行路由,并且可以取消待处理的请求以腾出空间。

答案 10 :(得分:4)

我知道这是一个老问题,但仍然......还有dhtmlxGrid可以处理数百万行。有一个演示with 50,000 rows但是可以在网格中加载/处理的行数是无限的。

免责声明:我来自DHTMLX团队。

答案 11 :(得分:3)

免责声明:我严重使用YUI DataTable 长时间没有头痛。它强大而稳定。根据您的需要,您可以使用ScrollingDataTable支持

  • 的x滚动
  • 的y滚动
  • XY-滚动
  • 强大的事件机制

根据您的需要,我认为您想要的是 tableScrollEvent 。它的API说

  

当固定滚动的DataTable有滚动时触发。

由于每个DataTable都使用DataSource,您可以通过tableScrollEvent 监控其数据以及渲染循环大小,以便根据您的需要填充ScrollingDataTable。

渲染循环大小说

  

如果您的DataTable需要显示整个非常大的数据集, renderLoopSize配置可以帮助管理浏览器DOM呈现,以便UI线程不会被锁定在非常大的表上。任何大于0的值都将导致DOM渲染在setTimeout()链中执行,这些链在每个循环中呈现指定的行数。理想值应根据实施情况确定,因为没有严格的规则,只有一般指导原则:

  • 默认情况下,renderLoopSize为0,因此所有行都在单个循环中呈现。 renderLoopSize&gt; 0会增加开销,所以请慎重使用。
  • 如果您的数据集足够大(行数X列X格式复杂性),用户在视觉呈现中遇到延迟和/或导致脚本挂起,考虑设置renderLoopSize
  • 50以下的renderLoopSize可能不值得。 renderLoopSize&gt; 100可能更好。
  • 除非数据集有数百行,否则可能认为数据集不够大。
  • 拥有renderLoopSize&gt; 0和&lt; total rows确实会导致表在一个循环中呈现(与renderLoopSize = 0相同),但它也会触发从单独的setTimeout线程处理后渲染行条带化等功能。

例如

// 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
 });

&LT; WHERE_DOES_THE_DATA_COME_FROM&GT;只是一个DataSource。它可以是JSON,JSFunction,XML甚至是单个HTML元素

Here你可以看到我提供的简单教程。请注意没有其他 DATA_TABLE pluglin同时支持单击和双击。 YUI DataTable允许你。而且,即使使用JQuery也可以使用它而不会头疼

一些例子,你可以看到

随意询问有关YUI DataTable的其他任何内容。

的问候,

答案 12 :(得分:3)

答案 13 :(得分:3)

我有点不明白,对于jqGrid你可以使用虚拟滚动功能:

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

但是再次,可以完成数百万行过滤:

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

我真的没有看到“好像没有页面”这一点,我的意思是......没有办法在浏览器中一次显示1,000,000行 - 这是10MB的HTML raw,我有点不明白为什么用户不想看到这些页面。

总之...

答案 14 :(得分:2)

我能想到的最好的方法是在滚动结束之前为每个滚动或某个限制加载json格式的数据块。 json可以很容易地转换为对象,因此可以轻松地构建表行

答案 15 :(得分:1)

我知道这个问题已有几年了,但jqgrid现在支持虚拟滚动:

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

但禁用了分页

答案 16 :(得分:1)

我强烈推荐 Open rico 。 它很难在一开始就实现,但一旦你抓住它就永远不会回头。

答案 17 :(得分:0)

我建议使用sigma grid,sigma grid嵌入了可以支持数百万行的分页功能。而且,您可能需要远程分页才能执行此操作。 看看演示 http://www.sigmawidgets.com/products/sigma_grid2/demos/example_master_details.html

答案 18 :(得分:0)

看看dGrid:

http://dojofoundation.org/packages/dgrid/

我同意用户永远不需要同时查看数百万行数据,但dGrid可以快速显示它们(一次只能屏幕显示)。

不要煮海洋煮一杯茶。