在 table 行的 on-demand 实例化中使用 React 将大 table 加载到网络浏览器中

Load big table into web browser using react in on-demand instantiation of table row

我正在使用 React.js 将 Excel-like table 构建到 Web 浏览器中,仅使用 <div> 而不是 <table>。 列数约为 90,行数约为 24000。

我们知道,由于性能问题,不可能在单个网页上将整个数据加载到 HTML。 所以我决定使用滚动向用户显示部分数据。

主要概念很简单,在用户视口附近构建 HTML。 猜测用户是否在单个视口中看到第 1800 到 1900 个数据。我将只加载大约第 1750 ~ 1950 个数据到 HTML。如果用户向上滚动,我将加载 HTML 第 1700 ~ 1750 条数据并删除第 1900 ~ 1950 条数据。

我想我需要手动操作滚动偏移来获取用户所在的位置。如果每行的高度与 40px 相同,视口的高度为 1000px,那么用户将在单个视口看到 25 个项目,所以我需要加载大约 25(前面)+ 25(当前看到的)+ 25(结束)数据,如果用户向上或向下,我将加载额外的数据并删除远离用户的数据。

但是,我发现,我的table要求与这种情况不匹配。这是我的情况。

首先,每一行的高度是不一样的。基本上我的 table 会将一行行显示为单行。我的意思是,table 单行可以如下所示,

| Photo|   ProductName |    Size Pool      |     Stock  |
.... // Below are single row
+------+---------------+-------------------+------------+
|      |     Boots     |   110-120         |      24    |  // Row header (Shows Summary of child row)
+      +---------------+-------------------+------------+  
|      |     Boots     |   110             |      16    |  // Row's row #1
+      +---------------+-------------------+------------+
|      |     Boots     |   120             |      8     |  // Row's row #2
+------+------------------------------------------------+
...
+------+---------------+-------------------+------------+
|      |Leather Shoe   |   120             |      8     |  // Row can come with no header row, only single
+------+---------------+-------------------+------------+
...

像上面一样,如果产品有超过 2 个选项,那么它会合并成一行一行并显示摘要 header。如果不是选项产品,它只显示它的行。如果行内的内容很大,它会拉伸以适应里面的内容 所有数据都来自远程数据库,它通过 REST API.

检索数据

数据库方案如下,2 table为例。

Table #1 ProductInfo
+--------------+------------+------------+-----------+
|  GroupNumber |ProductName |    Size    |   Stock   |
+--------------+------------+------------+-----------+
|       1      |   Boots    |    110     |   16      |
+--------------+------------+------------+-----------+
|       1      |   Boots    |    120     |    8      |
+--------------+------------+------------+-----------+
|       2      |Leather Shoe|    120     |    8      |  
+--------------+------------+------------+-----------+
Table #2 GroupInfo
+-----------+------------+--------------+
|GroupNumber|  SizePool  |   ImageURL   |
+-----------+------------+--------------+
|    1      |   110-120  |  https://abc |
+-----------+------------+--------------+
|    2      |    120     | https://def  |
+-----------+------------+--------------+

下面是未来的需求,(大部分已经实现)

  1. 按每列排序,multi-pivot按行或行排序(通过SQL处理)

  2. 按表达式过滤数据(由客户端处理)

  3. 隐藏、调整大小、更改列的顺序(由客户端处理)

  4. Interactable 单元格内的组件,如 DatePicker,Pop-up 等...(由客户端处理)

我使用基于页面的方法成功创建了这样的 table。但我需要滚动视口 table。 table 包含许多依赖值列,如总和、平均值,除非特殊原因(如性能),否则不会存储在数据库中。 (其中大部分由 DB View 或 Procedure 处理,包括排序、计算等)。所以整体表现真的很重要。

我考虑了几个问题和处理方法,你能检查一下并给我一个建议吗?

Q1。我如何决定何时应该加载和删除数据及其数量?

Q2。我可以通过两种不同的方式从数据库中获取数据。

Q3。如果我得到像{ group:<GroupINfo>, values:[<ProductInfo>,...] }这样的数据,性能有问题吗?

Q4。如果我从数据库中裁剪整个数据并在开始时进行结构化,并且只加载和删除 DOM 的数据,这是一个好方法吗?

我考虑过使用Infinite-Scrolling,但这不适合我的情况,我需要同时执行加载数据和删除数据。但是 infinite-scrolling 似乎不支持从视口中删除数据。行高不一致也可能是个问题。

我发现 react-virtualized 并且有效。 它还支持动态调整行的大小,这对我们帮助很大