React performance: rendering big list with PureRenderMixin

后端 未结 3 1423
离开以前
离开以前 2020-12-13 14:36

I took a TodoList example to reflect my problem but obviously my real-world code is more complex.

I have some pseudo-code like this.

var Todo = React         


        
3条回答
  •  心在旅途
    2020-12-13 15:19

    In our product we also had issues related to the amount of code being rendered, and we started using observables (see this blog). This might partially solve your problem, as changing todo will no longer require the parent component that holds the list to be re-rendered (but adding still does).

    It might also help you in re-rendering the list faster as your todoItem components could just return false when the props change on shouldComponentUpdate.

    For further performance improvements when rendering the overview, I think your tree / paging idea is nice indeed. With observable arrays, each page could start to listen to array splices (using an ES7 polyfill or mobservable) in a certain range. That would introduce some administration, as these ranges might change over time, but should get you to O(log(n))

    So you get something like:

    var TodosContainer = React.createClass({
      componentDidMount() {
         this.props.todos.observe(function(change) {
             if (change.type === 'splice' && change.index >= this.props.startRange && change.index < this.props.endRange)
                 this.forceUpdate();
         });
      },    
    
      renderTodo: function(todo) {
         return ;
      },
    
      render: function() {
         var todos = this.props.todos.slice(this.props.startRange, this.props.endRange).map(this.renderTodo)
         return (
              
                     {todos}
              ,
         );
      }
    
    });
    

    The central problem with large lists and react seems that you cannot just shift new DOM nodes into the dom. Othwerwise you won't need the 'pages' at all to partition the data in smaller chunks and you could just splice one new Todo item into the dom, as done with JQuery in this jsFiddle. You could still do that with react if you use a ref for each todo item, but that would be working around the system I think as it might break the reconciliation system?

提交回复
热议问题