From 225fe675865130e61988cd2d27e12bd0ca7e9826 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 30 Aug 2017 19:14:26 +0100 Subject: [PATCH] Fix room change sometimes being very slow If the js-sdk had a lot of history in memory for a particular room, riot would paginate all that history into the DOM and render it when switching to that room (before then removing it all again). This obviously made switching to that room very slow. This was caused by the fact that we relied on the setState that happens in TimelinePanel after the pagination taking effect such that ScrollPanel sees that it no longer needs to paginate, but in some situations (as far as I can see, in electron...?) this setState would not take effect until the pagination stopped fulfiling requests from memory and hit the network. Fix: don't resolve the promise returned by the pagination request until the setState has actually happened. --- src/components/structures/TimelinePanel.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 3e59a5aae4..1ef09e0719 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -344,9 +344,20 @@ var TimelinePanel = React.createClass({ newState[canPaginateOtherWayKey] = true; } - this.setState(newState); + // Don't resolve until the setState has completed: we need to let + // the component update before we consider the pagination commpleted, + // otherwise we'll end up paginating in all the history the js-sdk + // has in memory because we never gave the component a chance to scroll + // itself into the right place + let resolveSetStatePromise; + const setStatePromise = new Promise(function(resolve) { + resolveSetStatePromise = resolve; + }); + this.setState(newState, () => { + resolveSetStatePromise(r); + }); - return r; + return setStatePromise; }); },