在 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 |
+-----------+------------+--------------+
下面是未来的需求,(大部分已经实现)
按每列排序,multi-pivot按行或行排序(通过SQL处理)
按表达式过滤数据(由客户端处理)
隐藏、调整大小、更改列的顺序(由客户端处理)
Interactable 单元格内的组件,如 DatePicker,Pop-up 等...(由客户端处理)
我使用基于页面的方法成功创建了这样的 table。但我需要滚动视口 table。
table 包含许多依赖值列,如总和、平均值,除非特殊原因(如性能),否则不会存储在数据库中。 (其中大部分由 DB View 或 Procedure 处理,包括排序、计算等)。所以整体表现真的很重要。
我考虑了几个问题和处理方法,你能检查一下并给我一个建议吗?
Q1。我如何决定何时应该加载和删除数据及其数量?
- 数据高度不一致,所以我觉得不能用scroll offset或者data number作为衡量标准。 (是否可以使用 predictable 方式?)
- 是否可以通过访问DOM元素来存档?我是网络开发新手。对不起。
Q2。我可以通过两种不同的方式从数据库中获取数据。
- 分别获取 ProductInfo 和 GroupInfo
[<ProductInfo>,...]
和 [<GroupInfo>,...]
- 获取 object 喜欢这样的单个组
{ group:<GroupINfo>, values:[<ProductInfo>,...] }
在这种情况下,在典型情况下哪个性能更好?
Q3。如果我得到像{ group:<GroupINfo>, values:[<ProductInfo>,...] }
这样的数据,性能有问题吗?
- 就像查询开销一样(我需要使用查询连接 6 次,最大嵌套深度 6 SELECT 查询和 30 个计算列用于单次数据检索尝试。-- Pre-calculated 视图或 table 可能会有问题,因为我有很多用户使用它并且经常更新。所以我至少在更新时需要担心互斥。
- 如果我得到像
[<ProductInfo>,...]
和 [<GroupInfo>,...]
这样的数据,我确信上述查询的性能足以进行裁剪。但是我觉得后面一个更好。所以我需要尽可能更改界面。
Q4。如果我从数据库中裁剪整个数据并在开始时进行结构化,并且只加载和删除 DOM 的数据,这是一个好方法吗?
- 当然,Q1 是我的首要任务,但这似乎也不错,除了与 DB 的数据同步(因为其他用户可以更新值,而客户端包含过时的数据)
我考虑过使用Infinite-Scrolling,但这不适合我的情况,我需要同时执行加载数据和删除数据。但是 infinite-scrolling 似乎不支持从视口中删除数据。行高不一致也可能是个问题。
我发现 react-virtualized 并且有效。
它还支持动态调整行的大小,这对我们帮助很大
我正在使用 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 |
+-----------+------------+--------------+
下面是未来的需求,(大部分已经实现)
按每列排序,multi-pivot按行或行排序(通过SQL处理)
按表达式过滤数据(由客户端处理)
隐藏、调整大小、更改列的顺序(由客户端处理)
Interactable 单元格内的组件,如 DatePicker,Pop-up 等...(由客户端处理)
我使用基于页面的方法成功创建了这样的 table。但我需要滚动视口 table。 table 包含许多依赖值列,如总和、平均值,除非特殊原因(如性能),否则不会存储在数据库中。 (其中大部分由 DB View 或 Procedure 处理,包括排序、计算等)。所以整体表现真的很重要。
我考虑了几个问题和处理方法,你能检查一下并给我一个建议吗?
Q1。我如何决定何时应该加载和删除数据及其数量?
- 数据高度不一致,所以我觉得不能用scroll offset或者data number作为衡量标准。 (是否可以使用 predictable 方式?)
- 是否可以通过访问DOM元素来存档?我是网络开发新手。对不起。
Q2。我可以通过两种不同的方式从数据库中获取数据。
- 分别获取 ProductInfo 和 GroupInfo
[<ProductInfo>,...]
和[<GroupInfo>,...]
- 获取 object 喜欢这样的单个组
{ group:<GroupINfo>, values:[<ProductInfo>,...] }
在这种情况下,在典型情况下哪个性能更好?
Q3。如果我得到像{ group:<GroupINfo>, values:[<ProductInfo>,...] }
这样的数据,性能有问题吗?
- 就像查询开销一样(我需要使用查询连接 6 次,最大嵌套深度 6 SELECT 查询和 30 个计算列用于单次数据检索尝试。-- Pre-calculated 视图或 table 可能会有问题,因为我有很多用户使用它并且经常更新。所以我至少在更新时需要担心互斥。
- 如果我得到像
[<ProductInfo>,...]
和[<GroupInfo>,...]
这样的数据,我确信上述查询的性能足以进行裁剪。但是我觉得后面一个更好。所以我需要尽可能更改界面。
Q4。如果我从数据库中裁剪整个数据并在开始时进行结构化,并且只加载和删除 DOM 的数据,这是一个好方法吗?
- 当然,Q1 是我的首要任务,但这似乎也不错,除了与 DB 的数据同步(因为其他用户可以更新值,而客户端包含过时的数据)
我考虑过使用Infinite-Scrolling,但这不适合我的情况,我需要同时执行加载数据和删除数据。但是 infinite-scrolling 似乎不支持从视口中删除数据。行高不一致也可能是个问题。
我发现 react-virtualized 并且有效。 它还支持动态调整行的大小,这对我们帮助很大