javascript-在React中构建大型的multiselect而不是真的很慢

我正在构建的应用程序需要相当多的选择.它在用户界面中工作,因为我使用的是this library,它使人们可以搜索选项,但是我无法在合理的时间内在React中渲染它.

Link to JSFiddle.

我制作了一个更简单的版本来显示相同​​的问题.

它包含一些设置代码,该代码创建了500个项目的列表.它还列出了默认情况下应选择的项目.现在,我将其设置为x%1,因此默认情况下每个选项都处于启用状态,因为这似乎是瓶颈.我还启动了startTime变量只是为了跟踪事物.

var list = [];
var defaultList = [];
for (var x = 0; x < 500; x += 1) {
  list.push(x);
  if (x%1 === 0) {
    defaultList.push(x)
  }
}
var startTime=new Date().getTime();

然后,使用ReactDom.render()将其传递到组件中,该组件具有一个回调,用于提醒渲染后经过了多少毫秒:

ReactDOM.render(
  <Hello
    list={list}
    defaultList={defaultList}  
  />,
  document.getElementById('container'),
  ()=>{
    alert(new Date().getTime() - startTime)
  }
);

最后,组件本身仅对列表中的所有选项进行简单的多选,并默认检查defaultList中的所有选项:

var Hello = React.createClass({
  render: function() {
    return (
        <select defaultValue={this.props.defaultList} multiple>
        {this.props.list.map(item => {
            return (<option value={item} key={item}>{item}</option>)
        })}
      </select>
    )
  }
});

在我的计算机上运行此小提琴会产生一个警报,该警报显示要渲染此组件的时间超过1000毫秒.如果我将默认列表的限定词从x%1更改为xP,那么有10个选定项,则只需76毫秒.

最初,我认为瓶颈只是建立500个option元素,但似乎减速实际上是由于使用大量默认值造成的.

所以我想我的问题是:

>是否有人知道获得相同结果以更快渲染的方法?
>关于React性能,我是否缺少一些见识?
>为什么添加默认值会增加这么多开销?

谢谢.

而且请注意,我知道React在JSFiddle中的运行速度会变慢,并且在生产环境中,我应该使用React的生产版本,并且如果我不将清单中的500个项目排得很长,也就不会花那么长时间.这些不是我要的答案.

编辑:看起来React可能一次将每个选项都标记为选中的选项,从而导致500个rerender.这也许可以解释发生了什么-这是React中的错误吗?我看到“强制同步布局是可能的性能瓶颈”. Chrome开发者工具中的警告.

解决方法:

您所看到的是DOM的第一个渲染缓慢.采取以下代码:

let html = '<select multiple>'
for (var x = 0; x < 500; x += 1) {
  html += `<option value=${x} selected>${x}</option>`
}
html += '</select>'

var startTime=new Date().getTime();

document.getElementById('container').innerHTML = html;

alert(new Date().getTime() - startTime)

jsfiddle

它的性能与您在我的计算机(Chrome 47,Windows 10)上的反应代码相同,约为5000毫秒.

如果使用Microsoft Edge,则时间从5000毫秒变为231毫秒(反应时间)和12毫秒(DOM操作).在这里,Chrome DOM较慢(与Edge相比),并且必须将选项元素最终呈现为DOM.更新可能更快.

我做了一些相同的代码,但不是< select>领域.这是一个无序列表,列表项具有单击处理程序.性能提高了约10倍(Chrome约为500ms,Edge约为300ms).

class Select extends React.Component {
  constructor (props) {
    super(props)
    this.state = {}
    this.state.selected = props.selected
  }
  handleClick () {
    this.setState({selected: !this.state.selected})
  }
  render () {
    const val = this.props.value
    const selected = this.state.selected
    return (
      <li onClick={this.handleClick.bind(this)} className={selected ? 'selected' : ''}>
        {val}
      </li>
    )
  }
}

const Hello = ({list, defaultList}) => 
  <ul>
    {list.map(item =>
      <Select key={item} value={item} selected={defaultList.indexOf(item) !== -1}/>)}
  </ul>

jsfiddle

上一篇:javascript-React / Redux-假设我们有两个单独的待办事项列表,分别是已完成和未完成


下一篇:javascript-使用React Form,Flask服务器和Flask-WTF的CSRF保护