V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
tomoya92
V2EX  ›  问与答

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

  •  
  •   tomoya92 · 2019-07-29 16:59:31 +08:00 · 2800 次点击
    这是一个创建于 1974 天前的主题,其中的信息可能已经有所发展或是发生改变。

    技术栈:

    • react
    • react-redux
    • ant.design

    问题:

    现在项目开发了一个页面,里面全是表单,固定的(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 事件


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

    6 条回复    2019-07-29 17:50:54 +08:00
    upcliucong
        1
    upcliucong  
       2019-07-29 17:17:59 +08:00 via iPad
    GitHub repository 贴一下?
    tomoya92
        2
    tomoya92  
    OP
       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
        3
    maichael  
       2019-07-29 17:37:32 +08:00
    单独测试动态表单(把其他的注释掉),如果只有这个情况下,超过两百行都已经会卡顿,说明这个需求就是有问题的。否则的话就可能是组件状态没有划分清楚,导致全局渲染影响性能。
    但无论怎么说,一个页面几百个输入框怎么说都是不可接受的,尝试从产品的角度去优化,例如把大表单切割成几个小表单等。
    tomoya92
        4
    tomoya92  
    OP
       2019-07-29 17:41:02 +08:00
    @maichael #3 做过这方面的测试,单纯用 html 中的 form 来写,没用 antd 写,大约到 500 个以上就开始有卡顿了,这还只是绑了 onChange 事件,没有绑其它事件

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

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

    所以这个页面没法拆开。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3260 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:30 · PVG 20:30 · LAX 04:30 · JFK 07:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.