-
Notifications
You must be signed in to change notification settings - Fork 141
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
Performance issue with notifyObservers
#161
Comments
I would recommend getters that are used by other getters to always return immutable versions of objects. And getters that are consumed by components can return coerced |
In my case, the getter was the root for several other getters, but was also used directly in a component. I suppose I could write another simple getter to wrap the Immutable one, whose only purpose is to do the This seems like a separation worth mentioning in the docs somewhere. |
Thinking about this a bit more, it seems wrong for some getters to return Immutable objects and others to return JS objects. It makes it harder to compose them, and you may end up with two getters for each piece of data, one for composing and one for using the data in a component. What if, instead, getters always return ImmutableJS objects, so composing them is easy, and then have Nuclear call |
So for now, I've refactored my getters so they are all using ImmutableJS, but I renamed them to end in "Imm". None of these are directly used by components. They are only used to compose. Then I added new getters named without "Imm" that the components actually use. // This is the original data source and it set to an Immutable map
export let data = ['query', 'data'];
// This getter is only used as a dependency of passFailSummaryImm
export let summaryImm = [
data,
(data) => {
// Do some ImmutableJS manipulations here
return result;
}
];
// This getter is only used as a dependency of passFailSummary
export let passFailSummaryImm = [
summaryImm,
(summary) => {
// Do some ImmutableJS manipulations here
return result;
}
];
// This getter is the one my components actually use
export let passFailSummary = [
passFailSummaryImm,
(summary) => summary ? summary.toJS() : undefined
]; My non-immutable getters were previously taking 2500ms in When I have some time, I think I will change my smart components to use ImmutableJS too, and have them do any Then I can also get rid of the non-Immutable getters and drop the "Imm" extension. |
I meant to also mention that I am okay to close this issue now. I previously thought that it was expected to always convert to JS before using data in components, but now I see that you may or may not want to do that, so having Nuclear do that for you automatically would not always be what you want. In fact, it's probably better to always use Immutable where you can in your smart components. If automatic |
I was just tracking down a performance issue and have across what seems to be the root of the issue.
I would type into an
<input>
control whose value is managed by a Nuclear store, but the characters would take a long time to appear (150-200ms). This was the time from dispatching the action, until the render method was called.Tracking this down I found that in
notifyObservers
, some calls toevaluate()
were consistently taking a long time and not being cached.This turned out to be related to a getter that looked like this (with about 2MB of data):
Changing the return to the following fixed this (and other) performance issues:
I needed to add a call in a dependent getter to
data.toJS()
though to compensate (this data is not used directly, but only as dependencies of other getters).The problem seems to be that
data.toJS()
returns a new object every time, so the getter is never cached. Moving it up the chain just "fixed" the problem by avoiding it though.So my question is, what are the recommended practices for when and where to call
toJS()
? I feel like components should only work with plain objects, so currently all my getters return plain objects, not ImmutableJS objects, but I'm not sure if that's how others are using Nuclear.Thanks.
The text was updated successfully, but these errors were encountered: