求助, React 项目开发页面中有大量表单(详见内容),怎么保证性能?或者有什么解决方案?

2019-07-29 16:59:31 +08:00
 tomoya92

技术栈:


问题:

现在项目开发了一个页面,里面全是表单,固定的(input, select)大约有 35 个,还有三大块是动态输入框(就是点击一个按钮,添加一行的表单,一行少的有 3 个,多的有 9 个,有 input,select )

产品要求:

  1. 三大块动态表单要支持快捷键,就是按键盘上的+自动增加一行,按-就删除当前行
  2. 三大块动态表单中每个都有自动完成的功能,类似于 jqueryui 的 autocomplete 功能
  3. 如果是 select 或者自动完成的表单,当选择(选中)一个值后,焦点自动跳转到下一个输入框里
  4. 在提交的时候,后台做完校验,如果有错,返回的数据还要解析出来哪些 input 或者 select 有问题,然后给它们加个红框
  5. 上面红框提示的同时还要弹一个通知,
  6. 还有一些其它的联动操作,比如固定表单中某个 select 值发生了变化,动态表单中有一项 select 也要跟着变之类的

其它固定的 input 和 select 还好说,问题出在动态增加的那三块表单中,其中一行就有 9 个 input (和 select )的表单少的几行,多的几百上千行,这时候性能问题就出来了,经测试,超过 200 行就基本没法填内容了,卡的不要不要的(这是原生 html 组件写的性能) ant.design 加上后,超过 50 行(也就是 450 个 input/select)就卡的没法输入了

因为要绑定快捷键事件,所以对表单中的 input/select 都做了事件绑定( onFocus, onBlur, onChange),特别是 onChange 事件,因为它对 state 修改了,每次修改 state 页面就会刷新,这也是卡的主要原因

但如果不用 onChange 来做双向数据绑定,那提交的时候,页面上的数据获取就相当的麻烦了

还有全局事件绑定怎么处理比较好,因为三大块动态表单都用的是一个快捷键,所以只能在父组件中处理了,这就要在子组件里往父组件反馈,也就是需要用到 onFocus 或者 onBlur 事件


综上,求大神有好的解决方案分享一下,谢谢!

2697 次点击
所在节点    问与答
6 条回复
upcliucong
2019-07-29 17:17:59 +08:00
GitHub repository 贴一下?
tomoya92
2019-07-29 17:20:39 +08:00
@upcliucong #1 公司的项目,代码不好分享,不过我画了个界面的图,大佬可以参考一下

![QQ20190729-171153]( https://user-images.githubusercontent.com/6915570/62036830-22ddb500-b225-11e9-8dcc-22d2b7e173d1.png)
maichael
2019-07-29 17:37:32 +08:00
单独测试动态表单(把其他的注释掉),如果只有这个情况下,超过两百行都已经会卡顿,说明这个需求就是有问题的。否则的话就可能是组件状态没有划分清楚,导致全局渲染影响性能。
但无论怎么说,一个页面几百个输入框怎么说都是不可接受的,尝试从产品的角度去优化,例如把大表单切割成几个小表单等。
tomoya92
2019-07-29 17:41:02 +08:00
@maichael #3 做过这方面的测试,单纯用 html 中的 form 来写,没用 antd 写,大约到 500 个以上就开始有卡顿了,这还只是绑了 onChange 事件,没有绑其它事件

之前也考虑过将一行 9 个表单的那块做成分页的,这样可以减少页面表单的数量,但全页面还要做校验,录入人员还要去修改数据,做成分页不方便修改
maichael
2019-07-29 17:47:14 +08:00
@tomoya92 #4 如果几个表单之间没有关联,可以考虑直接独立开来,至于那个大表单就只能做成分页的,或者滚动分页的,确保页面渲染出来的条数在可控范围内就行。
tomoya92
2019-07-29 17:50:54 +08:00
@maichael #5 几个表单之间是有关联的

1. 提交的时候要做校验,校验规则中有些是从不同表单中获取数据进行+-x/运算比较,如果有问题页面上还要做响应
2. 上面我画的图中也画了一条,最上面那个表单如果有变化,下面表单中的 select 也会跟着变化
3. 几个自动完成的 input 在请求数据的时候,也要从其它表单中获取一些数据来当作参数

所以这个页面没法拆开。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/587229

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX