React Performance: Rendern einer großen Liste mit PureRenderMixin

Ich habe ein TodoList-Beispiel verwendet, um mein Problem darzustellen, aber offensichtlich ist mein Code in der realen Welt komplexer.

Ich habe so einen Pseudocode.

var Todo = React.createClass({
  mixins: [PureRenderMixin], 
  ............ 
}

var TodosContainer = React.createClass({
  mixins: [PureRenderMixin],    

  renderTodo: function(todo) {
     return <Todo key={todo.id} todoData={todo} x={this.props.x} y={this.props.y} .../>;
  },

  render: function() {
     var todos = this.props.todos.map(this.renderTodo)
     return (
          <ReactCSSTransitionGroup transitionName="transition-todo">
                 {todos}
          </ReactCSSTransitionGroup>,
     );
  }

});

Alle meine Daten sind unveränderlich und PureRenderMixin wird entsprechend verwendet und alles funktioniert einwandfrei. Wenn Todo-Daten geändert werden, werden nur die übergeordneten und die bearbeiteten Aufgaben neu gerendert.

Das Problem ist, dass meine Liste irgendwann größer wird, wenn der Benutzer einen Bildlauf durchführt. Und wenn ein einzelnes Todo aktualisiert wird, dauert es immer länger, das übergeordnete Element zu rendern. Rufen Sie @ aushouldComponentUpdate auf allen Aufgaben, und rendern Sie dann die einzelne Aufgabe.

Wie Sie sehen, hat die Todo-Komponente eine andere Komponente als die Todo-Daten. Dies sind Daten, die für das Rendern aller Aufgaben benötigt werden und die gemeinsam genutzt werden (wir könnten uns beispielsweise vorstellen, dass es für die Aufgaben einen "displayMode" gibt). Mit vielen Eigenschaften macht dasshouldComponentUpdate etwas langsamer ausführen.

Auch mitReactCSSTransitionGroup scheint auch etwas langsamer zu werden, daReactCSSTransitionGroup muss sich rendern undReactCSSTransitionGroupChild noch vor demshouldComponentUpdate von todos heißt.React.addons.Perf zeigt, dassReactCSSTransitionGroup > ReactCSSTransitionGroupChild Rendering ist Zeitverschwendung für jedes Element der Liste.

So, soweit ich weiß, verwende ichPureRenderMixin aber bei einer größeren Liste reicht dies möglicherweise nicht aus. Ich bekomme immer noch keine so schlechten Leistungen, würde aber gerne wissen, ob es einfache Möglichkeiten gibt, meine Renderings zu optimieren.

Irgendeine Idee

Bearbeite:

Bisher ist meine große Liste paginiert, daher teile ich diese große Liste jetzt in eine Liste von Seiten auf, anstatt eine große Liste von Elementen zu haben. Dies ermöglicht eine bessere Leistung, da jede Seite jetzt @ implementieren kanshouldComponentUpdate. Wenn sich ein Element auf einer Seite ändert, muss React nur die auf der Seite durchlaufene Hauptrenderfunktion aufrufen und die Renderfunktion nur von einer einzelnen Seite aus aufrufen, wodurch die Iterationsarbeit erheblich verringert wird.

Meine Renderleistung ist jedoch immer noch linear zur Seitenzahl (O (n)), die ich habe. Wenn ich also Tausende von Seiten habe, ist es immer noch dasselbe Problem :) In meinem Anwendungsfall ist es unwahrscheinlich, dass es passiert, aber ich bin immer noch an einer besseren Lösung interessiert.

Ich bin mir ziemlich sicher, dass es möglich ist, eine O (log (n)) - Renderleistung zu erzielen, wobei n die Anzahl der Elemente (oder Seiten) ist, indem eine große Liste in einen Baum (wie eine persistente Datenstruktur) aufgeteilt wird und wo jedes Element Knoten hat die Macht, die Berechnung mit @ kurzzuschließshouldComponentUpdate

Ja, ich denke an etwas Ähnliches wie persistente Datenstrukturen wie Vector in Scala oder Clojure:

Ich mache mir jedoch Sorgen um React, da meines Wissens beim Rendern der internen Knoten des Baums möglicherweise Dom-Zwischenknoten erstellt werden müssen. Dies kann je nach Verwendungszweck ein Problem sein und möglicherweise in zukünftigen Versionen von React @ behob)

Auch wenn wir Javascript verwenden, frage ich mich, ob Immutable-JS dies unterstützt und die "internen Knoten" zugänglich macht. Sehen:https: //github.com/facebook/immutable-js/issues/54

Bearbeite: nützlicher Link zu meinen Experimenten:Kann eine React-Redux-App auch wirklich skalieren, sagen wir Backbone? Auch bei erneuter Auswahl. Auf dem Hand

Antworten auf die Frage(6)

Ihre Antwort auf die Frage