Wie optimiere ich kleine Updates für Requisiten verschachtelter Komponenten in React + Redux?

Beispielcode:https: //github.com/d6u/example-redux-update-nested-props/blob/master/one-connect/index.j

Live-Demo ansehen:http: //d6u.github.io/example-redux-update-nested-props/one-connect.htm

Wie kann man kleine Updates für Requisiten verschachtelter Komponenten optimieren?

Ich habe oben Komponenten, Repo und RepoList. Ich möchte das Tag des ersten Repos aktualisieren Line 14). Also habe ich ein @ geschicUPDATE_TAG Aktion. Bevor ich @ implementiert hashouldComponentUpdate, der Versand dauert ca. 200ms, was zu erwarten ist, da wir viel Zeit verschwenden.<Repo/>s die sich nicht geändert haben.

Nachdem hinzugefügtshouldComponentUpdate, Versand dauert ca. 30ms. Nach der Erstellung von React.js in der Produktion kosten die Updates nur noch ca. 17 ms. Dies ist viel besser, aber die Timeline-Ansicht in der Chrome-Dev-Konsole zeigt immer noch einen Jank-Frame an (länger als 16,6 ms).

Stellen Sie sich vor, wir haben viele Updates wie dieses oder<Repo/> ist komplizierter als das derzeitige, 60fps können nicht verwaltet werden.

Meine Frage ist, ob es für so kleine Aktualisierungen der Requisiten einer verschachtelten Komponente eine effizientere und kanonischere Möglichkeit gibt, den Inhalt zu aktualisieren. Kann ich Redux weiterhin verwenden?

Ich habe eine Lösung durch Ersetzen jedestags mit einem sichtbaren inneren Reduzierer. Etwas wi

// inside reducer when handling UPDATE_TAG action
// repos[0].tags of state is already replaced with a Rx.BehaviorSubject
get('repos[0].tags', state).onNext([{
  id: 213,
  text: 'Node.js'
}]);

Dann abonniere ich ihre Werte in der Repo-Komponente mithttps: //github.com/jayphelps/react-observable-subscrib. Das hat super geklappt. Jeder Versand kostet auch bei Entwicklung von React.js nur 5ms. Aber ich denke, das ist ein Anti-Pattern in Redux.

Update 1

Ich folgte der Empfehlung in Dan Abramovs Antwort und normalisiert meinen Zustand undaktualisierte Verbindungskomponenten

Die neue Statusform lautet:

{
    repoIds: ['1', '2', '3', ...],
    reposById: {
        '1': {...},
        '2': {...}
    }
}

Ich fügte hinzuconsole.time umReactDOM.render zu Zeitdas anfängliche Rendern.

Die Leistung ist jedoch schlechter als zuvor (sowohl beim ersten Rendern als auch beim Aktualisieren). (Quelle:https: //github.com/d6u/example-redux-update-nested-props/blob/master/repo-connect/index.j, Live-Demo:http: //d6u.github.io/example-redux-update-nested-props/repo-connect.htm)

// With dev build
INITIAL: 520.208ms
DISPATCH: 40.782ms

// With prod build
INITIAL: 138.872ms
DISPATCH: 23.054ms

Ich denke, auf jedem verbinden<Repo/> hat viel Overhead.

Update 2

Auf der Grundlage von Dans aktualisierter Antwort müssen wir @ zurückgebconnect 'smapStateToProps Argumente geben stattdessen eine Funktion zurück. Sie können Dans Antwort überprüfen. Ich habe auch @ aktualisiedie Demos.

Below, die Leistung ist auf meinem Computer viel besser. Und nur zum Spaß habe ich auch den Nebeneffekt im Reducer-Ansatz hinzugefügt, von dem ich gesprochen habe Quell, Dem) ernsthaft nicht verwenden, es ist nur zum Experimentieren).

// in prod build (not average, very small sample)

// one connect at root
INITIAL: 83.789ms
DISPATCH: 17.332ms

// connect at every <Repo/>
INITIAL: 126.557ms
DISPATCH: 22.573ms

// connect at every <Repo/> with memorization
INITIAL: 125.115ms
DISPATCH: 9.784ms

// observables + side effect in reducers (don't use!)
INITIAL: 163.923ms
DISPATCH: 4.383ms
Update 3

Gerade hinzugefügt reagieren-virtualisiertes Beispiel basierend auf "Bei jedem mit Auswendiglernen verbinden"

INITIAL: 31.878ms
DISPATCH: 4.549ms

Antworten auf die Frage(2)

Ihre Antwort auf die Frage