表单中的复杂内容
  在 Form 表单中不一定都是输入组件,也会包含展示组件。但是由于 Form 更新时会触发所有子组件的更新,所以表单里包含了一个很大的组件,例如 Tabs 数组,会造成性能瓶颈。
  示例页面:https://assweeecan.github.io/antd_performance_test/dist/index.html#/tag-page
  性能测试图:

  在使用 Form.create 的时候会给组件包裹一层 Form 组件。使用 this.props.form.getFieldDecorator 注册的组件会在 Form 的 state 中保存相应的数据,包括 value 、校验状态、错误信息。当表单的组件触发 onChange 时,Form 的 state 会发生改变,触发界面更新的同时也会触发子组件的更新。如果组件包含大量的循环节点,本身渲染很慢,会影响表单的性能。而 Input 对性能是敏感的,所以会出现输入卡顿的现象。
  控制台打印的是整个 Form 组件 componentWillUpdate 和 componentDidUpdate 的时间差,可以看到图中 scripting 花费了 1378ms, 打印出来的更新时间差也达到了 200ms以上,这足以造成输入卡顿。而组件更新时间小于 16ms 时用户输入才不会有卡顿感。你也可以自己试试看卡顿到了什么程度。
  将 tag 拆分成一个组件,并设置 shouldComponentUpdate。这样每次输入时不会触发 tag 的更新。
  示例页面:https://assweeecan.github.io/antd_performance_test/dist/index.html#/tag-optimized-page
  性能测试图:

  打印时间差已经缩短到 16ms 以内,用户不会再感受到卡顿。因此,在表单内容比较多的时候必须注意这些数量多但是又不经常更新的内容,将其拆分成子组件是一个好办法。
  表单中的复杂的域组件
  复杂的表单域组件也会影响性能。上面说了表单中的组件过于复杂的组件是会影响性能的。例如 antd 的选择框,在传入选项的时候使用了 Option 组件传入选项参数。由于 ReactElement 会在每次 Render 的时候生成新的对象,因此组件无法直接判断传入参数数组是否有变化,也是每次都会重新生成索引、生成界面。如果表单里有 Input 组件,用户在输入时会觉的卡顿。
  示例页面:https://assweeecan.github.io/antd_performance_test/dist/index.html#/select-page
  性能测试图:

  Select 是一个比较复杂的表单组件,我们可以看到,在 Input 中输入文本时 js 处理花费了大量时间。解决这个问题的方法是寻找一个高性能的 Select 组件替代,或者对原有组件进行包装,甚至是自己实现一个 Select 组件。
  示例页面:https://assweeecan.github.io/antd_performance_test/dist/index.html#/select-optimized-page
  性能测试图:

  可以看到打印时间从 50ms 降低到 10ms ,用户输入不会再感受到卡顿。 这里笔者对 Select 组件进行了一层包装,将原来由 Children 传入 Option 的方式改为传入一个 Option 数组,这样能更好的控制 Select 组件的更新以达到提高性能的目的。 包装 Select 组件示例:https://github.com/assweeecan/antd_performance_test/blob/master/app/scripts/components/commons/select-a.jsx
  当然我们还可以将 Select 组件替换为 Modal + Checkbox 的组合,这样用户可以获得更大的视野,性能也会提升。
  总结
  因为 React 有一种将更新范围扩大的特点,因此有些时候会遇到性能瓶颈,特别是在表单里。当我们使用 antd 遇到性能瓶颈的时候,可以在这方面进行优化。 以上的优化都是在不修改原有界面的情况下进行优化。然而要想彻底解决这些性能问题,应该从设计入手,减少表单域的数量,对选项进行分组和折叠,又或者使用弹窗显示一组复杂的表单域,尽可能设置默认值,才能从根本上解决性能问题,也会减少用户的工作量,获得更好的用户体验。