From 58eedd1c375372d6afbdd66cb945e894630800ea Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Fri, 15 Dec 2017 13:14:40 +0000 Subject: [PATCH] Cache the SyncGate calculations. This was taking quite a lot of time and caching this significantly improves performance. We only need it because of the react-redux-router bug, but good to have it in the meanwhile. --- package.json | 2 ++ src/SyncGate.tsx | 88 +++++++++++++++++++++++++++--------------------- yarn.lock | 10 ++++++ 3 files changed, 62 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index 1c6d9e3..f5c17db 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "redux-logger": "^3.0.6", "redux-persist": "^5.4.0", "redux-thunk": "^2.2.0", + "reselect": "^3.0.1", "sjcl": "git+https://github.com/etesync/sjcl", "urijs": "^1.16.1", "uuid": "^3.1.0" @@ -46,6 +47,7 @@ "@types/react-router-dom": "^4.2.3", "@types/redux-actions": "^2.2.3", "@types/redux-logger": "^3.0.5", + "@types/reselect": "^2.2.0", "@types/sjcl": "^1.0.28", "@types/urijs": "^1.15.34", "@types/uuid": "^3.4.3" diff --git a/src/SyncGate.tsx b/src/SyncGate.tsx index e332646..da36105 100644 --- a/src/SyncGate.tsx +++ b/src/SyncGate.tsx @@ -3,6 +3,7 @@ import { connect } from 'react-redux'; import { Route, Switch, Redirect, withRouter } from 'react-router'; import { List, Map } from 'immutable'; +import { createSelector } from 'reselect'; import { routeResolver } from './App'; @@ -33,6 +34,49 @@ interface PropsTypeInner extends PropsType { entries: EntriesType; } +const syncInfoSelector = createSelector( + (props: PropsTypeInner) => props.etesync, + (props: PropsTypeInner) => props.journals.value as List, + (props: PropsTypeInner) => props.entries, + (etesync, journals, entries) => { + return journals.reduce( + (ret, journal) => { + const derived = etesync.encryptionKey; + const journalEntries = entries.get(journal.uid); + const cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version); + + let prevUid: string | null = null; + + if (!journalEntries || !journalEntries.value) { + return ret; + } + + // FIXME: Skip shared journals for now + if (journal.key) { + return ret; + } + + const collectionInfo = journal.getInfo(cryptoManager); + + const syncEntries = journalEntries.value.map((entry: EteSync.Entry) => { + let syncEntry = entry.getSyncEntry(cryptoManager, prevUid); + prevUid = entry.uid; + + return syncEntry; + }); + + return ret.set(journal.uid, { + entries: syncEntries, + collection: collectionInfo, + journal, + journalEntries: journalEntries.value, + }); + }, + Map() + ); + }, +); + class SyncGate extends React.PureComponent { props: PropsTypeInner; @@ -68,42 +112,10 @@ class SyncGate extends React.PureComponent { return (); } - const derived = this.props.etesync.encryptionKey; + const journalMap = syncInfoSelector(this.props); - const journalMap = journals.reduce( - (ret, journal) => { - const journalEntries = this.props.entries.get(journal.uid); - const cryptoManager = new EteSync.CryptoManager(derived, journal.uid, journal.version); - - let prevUid: string | null = null; - - if (!journalEntries || !journalEntries.value) { - return ret; - } - - // FIXME: Skip shared journals for now - if (journal.key) { - return ret; - } - - const collectionInfo = journal.getInfo(cryptoManager); - - const syncEntries = journalEntries.value.map((entry: EteSync.Entry) => { - let syncEntry = entry.getSyncEntry(cryptoManager, prevUid); - prevUid = entry.uid; - - return syncEntry; - }); - - return ret.set(journal.uid, { - entries: syncEntries, - collection: collectionInfo, - journal, - journalEntries: journalEntries.value, - }); - }, - Map() - ); + const PimRouter = withRouter(Pim); + const JournalRouter = withRouter(Journal); return ( @@ -117,7 +129,7 @@ class SyncGate extends React.PureComponent { ( - ( - @@ -145,7 +157,7 @@ const mapStateToProps = (state: StoreState, props: PropsType) => { }; }; -// FIXME: withRouter is only needed here because of https://github.com/ReactTraining/react-router/issues/5795 +// FIXME: this and withRouters are only needed here because of https://github.com/ReactTraining/react-router/issues/5795 export default withRouter(connect( mapStateToProps )(SyncGate)); diff --git a/yarn.lock b/yarn.lock index 95e4f3a..4d13690 100644 --- a/yarn.lock +++ b/yarn.lock @@ -90,6 +90,12 @@ dependencies: redux "^3.6.0" +"@types/reselect@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@types/reselect/-/reselect-2.2.0.tgz#c667206cfdc38190e1d379babe08865b2288575f" + dependencies: + reselect "*" + "@types/sjcl@^1.0.28": version "1.0.28" resolved "https://registry.yarnpkg.com/@types/sjcl/-/sjcl-1.0.28.tgz#4693eb6943e385e844a70fb25b4699db286c7214" @@ -5021,6 +5027,10 @@ requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" +reselect@*, reselect@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" + resolve-dir@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"