Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sociogram Performance degrades substantially as redux store gets larger #1066

Open
jthrilly opened this issue Jul 30, 2020 · 5 comments
Open

Comments

@jthrilly
Copy link
Member

jthrilly commented Jul 30, 2020

The performance of the sociogram dragging degrades substantially as the redux store grows.

To reproduce:

  • install the development protocol
  • generate 10 sample sessions
  • Dragging on the sociogram (which emits a debounced action) becomes unusable. A variant of this issue has already been identified (Drag and Drop Performance issues #1031)
@jthrilly jthrilly added this to the stable milestone Jul 30, 2020
@jthrilly jthrilly changed the title Performance degrates substantially as redux store gets larger Sociogram Performance degrates substantially as redux store gets larger Jul 31, 2020
@jthrilly jthrilly changed the title Sociogram Performance degrates substantially as redux store gets larger Sociogram Performance degrades substantially as redux store gets larger Aug 4, 2020
@jthrilly jthrilly modified the milestones: stable, Beta-stretch Oct 16, 2020
@wwqrd
Copy link
Contributor

wwqrd commented Jan 19, 2021

@jthrilly Is this task still outstanding? I see that there was a merge against changing to a different storage backend, does that resolve this issue?

@jthrilly
Copy link
Member Author

jthrilly commented Jan 20, 2021

No, the data storage engine is one piece of this. This issue might be better re-phrased as "app performance generally degrades as the redux store grows".

The underlying speed of the storage system only papers over the cracks in this case (and actually, I'm not certain specifically how the performance of sqlite through a cordova plugin compares with the web view's local storage implementation - we just needed to do that for other reasons).

As I pointed out in the OP, there is another issue relevant to this here: #1031 (drag and drop performance hitches, which worsened as redux store grew).

I was able to resolve the above issue satisfactorily by correctly throttling edge update events, but once again the underlying issue is that interacting with large (and perhaps specifically deeply nested) objects in javascript is quite slow, and grows slower as the objects increase in size/complexity. Our state objects can end up being really quite large and complex, given we have (1) some number of protocols installed on the device with each containing a codebook and stage definitions, and (2) some number of sessions, each containing a full network data model, with those members themselves being collections of objects. I'm sure redux has a sophisticated diffing approach for fast updates, but I think this sort of thing is just slow in a single threaded context. Using local storage also makes this worse, because it requires serialisation.

You may recall that we discussed this on slack a while back. Our idea was to looking having separate stores. One for the app and its settings, one for protocols, and one for each session. I think looking into this is the only real solution to these issues.

@wwqrd
Copy link
Contributor

wwqrd commented Jan 20, 2021

So essentially every state change is causing a JSON.stringify() because it's persisted. I can see why that would slow things down! One immediate improvement that could be made to that is to not persist most of the stage interaction events, maybe "change stage" only.

In addition to separate redux stores, anything but the active protocol/session could be kept on disk and out of state.

@jthrilly
Copy link
Member Author

One immediate improvement that could be made to that is to not persist most of the stage interaction events, maybe "change stage" only.

Unfortunately, this would lead to a lot of data loss potential, so I don't think we can do it. The best solution is to increase the performance of the app following the example in #1031, and to separate out the stores so that each interview session always starts from a baseline performance, and only degrades according to its own contents.

@jthrilly jthrilly moved this to Maintainence in Network Canvas Aug 25, 2022
@jthrilly
Copy link
Member Author

On Sociogram performance specifically: this problem can be resolved by porting over the approach used on the force directed layout mode (RealtimeCanvas). This bypasses the react render cycle, and only emits actions at specific key moments (node layout completes, drag ends, etc.). Performance here is a smooth 60fps.

On the issue more broadly:

  • Significant amounts of re-rendering are happening due to state updates, as a result of redux-forms and our general lack of knowledge about this process when designing several systems. Improvements to these areas will help.
  • In general this work will be carried out as part of the fresco project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants