reactjs - 在表格行的按需实例化中使用反应将大表格加载到 Web 浏览器中
问题描述
我正在使用 React.js 在 Web 浏览器中构建一个类似 Excel 的表格,仅使用<div>
not <table>
. 列数约为 90,行数约为 24000。
众所周知,由于性能问题,不可能在单个网页上将整个数据加载到 HTML 中。所以我决定使用滚动向用户显示部分数据。
主要概念很简单,在用户视口附近构建 HTML。猜测用户是否在单个视口中看到第 1800 到第 1900 个数据。我只会将大约 1750 到 1950 的数据加载到 HTML 中。如果用户向上滚动,我将为第 1700 ~ 1750 个数据加载 HTML 并删除第 1900 ~ 1950 个数据。
我想我需要手动操作滚动偏移来获取用户所在的位置。如果每行的高度与 40px 相同,并且视口的高度为 1000px,那么用户将在单个视口看到 25 个项目,所以我需要加载大约 25(前)+ 25(当前看到)+ 25(结束)数据,如果用户上行或下行,我将加载额外的数据并删除远离用户的数据。
但是,我发现对我的表的要求与这种情况不匹配。这是我的情况。
首先,每一行的高度不一样。基本上我的表会将行显示为单行。我的意思是,表格单行可以如下所示,
| 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 个选项,那么它会合并为单行并显示摘要标题。如果不是选项产品,它只显示它的行。如果行内的内容很大,它将拉伸以适应里面的内容。所有数据都来自远程数据库,这些数据库通过 REST API 检索数据。
数据库方案如下,以2表为例。
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 |
+-----------+------------+--------------+
未来的要求如下,(并且大部分都已实现)
按每列排序,按行或行进行多轴排序(通过 SQL 处理)
按表达式过滤数据(由客户端处理)
隐藏、调整大小、更改列的顺序(由客户端处理)
单元格内的可交互组件,如 DatePicker、Pop-up 等...(由客户端处理)
我成功地用基于页面的方法创建了这样的表。但我需要滚动视口表。该表包含许多依赖值列,如 sum、average,除了特殊原因(如性能)外,它们不存储在 DB 中。(其中大部分由数据库视图或程序处理,包括排序、计算等)。所以整体性能真的很重要。
我考虑了几个问题和处理这个问题的方法,你能检查一下并给我一个建议吗?
Q1。我如何决定何时加载和删除数据及其数量?
- 数据高度不一致,所以我认为我不能使用滚动偏移或数据编号作为衡量标准。(有可能以可预测的方式吗?)
- 是否可以通过访问 DOM 元素进行归档?我是 Web 开发新手。对不起。
Q2。我可以通过两种不同的方式从数据库中获取数据。
- 分别获取 ProductInfo 和 GroupInfo
[<ProductInfo>,...]
和[<GroupInfo>,...]
- 在典型情况下,在这种情况下,获取单个组哪个对象
{ group:<GroupINfo>, values:[<ProductInfo>,...] }
对性能更好?
Q3。如果我得到类似的数据{ group:<GroupINfo>, values:[<ProductInfo>,...] }
,性能是否有问题?
- 像查询开销(我需要使用查询加入 6 次,最大 6 个深度嵌套的 SELECT 查询和 30 个计算列进行单次数据检索尝试。 - 预先计算的视图或表可能有问题,因为我有很多用户使用它和更新所以我至少在更新时需要担心互斥。
[<ProductInfo>,...]
如果我得到像And这样的数据,我确信上述查询的性能足以进行裁剪[<GroupInfo>,...]
。但是我觉得后面的更好。所以如果可能的话我需要改变界面。
Q4。如果我从数据库中裁剪整个数据并在开始时进行结构化,并且仅为 DOM 加载和删除数据,这会是一个好方法吗?
- 当然,第一季度是我的首要任务,但这似乎也不错,除了与数据库同步数据(因为其他用户可以更新值,而客户端包含过时的数据)
我考虑过使用无限滚动,但这不适用于我的情况,我需要同时执行加载数据和删除数据。但是无限滚动似乎不支持从视口中删除数据。不一致的行高也可能是一个问题。
解决方案
我发现 react-virtualized 并且它有效。它还支持行的动态调整大小,它有很大帮助
推荐阅读
- python - 删除重复项并过滤数据框
- java - 当另一个片段中的按钮尝试打开它时,时间选择器对话框会导致应用程序崩溃
- batch-file - 循环通过批处理文件中的输入参数
- javascript - 将 Vue/Angular 等 js 库与其他 javascript 资产相结合?
- python - 替换和扁平化 Numpy 数组
- javascript - 当 var 为 true 时,VueJS 会阻止对变量元素进行制表符
- azure - Azure 数据工厂 - 同步调用逻辑应用
- selenium - 使用 Selenium 和 IE 和 IEdriverServer 的自动化测试问题
- c++ - 从字符串中删除多余的空格
- php - Laravel 雄辩的 find() 具有自定义主键返回未找到