-
Notifications
You must be signed in to change notification settings - Fork 276
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
[sitecore-jss-react] Memory leak in SitecoreContext #414
Conversation
Now, removed this part from
So, before my fix, every component that was wrapped by |
Would be good to get some additional eyes internally or from the community on this breaking change. Any feedback from @kamsar @aweber1 @GaryWenneker @erzr? |
The original implementation of this was my code (sorry!) and it was to deal with some oddities involving nested placeholders and React updates. I don't 100% recall the exact details, but due to the way we dynamically compose components in the Placeholder component, we were having issues causing proper component invalidation when context data updated down multiple placeholders - the placeholder props weren't changing, so neither were the children even being evaluated for re-rendering so we opted to force update the specific components that subscribed to it. |
First, some history, then some feedback :) IIRC, one of the reasons for having a I don't believe the sample app demonstrates that type of usage, I think it was carried over from the original React "Advanced App". I also think much of the context-related code was built around the early (early) React Context API, which was not as stable or as functional as it is now. All of that said, I would probably recommend that the sample app be simplified and the responsibility of handling pub/sub of Layout Service context data be offloaded to documentation or implementation example. A few suggestions to that end:
|
If we are talking about exposing data/state outside the Router, isn't that a bigger problem that should/could be solved by access to the entirety of the Layout Service response? IIRC, our original examples actually got their navigation data from context (via the So what are the use cases for the |
Worth noting too that React docs show examples of updating context from a nested component. But here they do keep the state on the App vs in the provider. https://reactjs.org/docs/context.html#updating-context-from-a-nested-component |
@aweber1 Yes, it's recommended to store as state. Why can't we wrap whole application at the root level by |
TBH, I think removing the use of forceUpdate and context factory is the primary reason for enhanced SSR performance and fixed memory leak. Beyond that, I think we're in more of a philosophical discussion about React state management and JSS sample app architecture - a separate discussion if necessary but not particularly germane to the issue attached to this PR. |
@aweber1 True, but that philosophical discussion does affect what goes into the restructured |
Description
Investigation for performance issue of
node-headless-proxy
Purpose: get rid of subscribers, use
setState
instead offorceUpdate
.I'll cover by unit-tests if my changes could be accepted
Motivation
I prepared flame graph, you can download it, where you can see that with fix - SitecoreContext is not hottest
Also you can look at results.txt, it's result of load tests, 150 req, 20 users.
clinic flame --on-port 'artillery quick --count 150 -n 20 http://localhost:3000' -- node index.js
Flame Graph
: flames.zipsetState
instead offorceUpdate
. React recommend it: https://reactjs.org/docs/react-component.html#forceupdatesubscribers
, because it's not working like sockets, when app opened by 10 clients will share data at any time.At every request server push new subscriber, and that's it, server forget about new subscriber, because it can't do anything with it.
subscribers
- like a dead storage, that consumes more and more memory on every request, because we need to go through the all subscribers and callforceUpdate
on every request of the page. We can't unsubscribe, becausecomponentWillUnmount
is working only on client side.super(props, context)
is deprecated, instead have to use:super(props)
How Has This Been Tested?
Types of changes
/docs
directory)Checklist: