-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
Only re-render when you need to (Potentially huge perf boost) #1176
Comments
To add to the discussion: facebook/react#2517. |
Hmm. Is it common to change If it is common though; maybe make this an opt in? |
@nevir This can be a good tradeoff |
Thanks @JAStanton - There also a discussion about this same issue in #1040 I agree with @oliviertassinari that @nevir's idea seems like a good tradeoff. |
(Or maybe opt out, actually, if you think a static theme is the norm) |
@hai-cea I believe that this is a more general issue than #1040. |
Till this issue with context is not fixed upstream, the PureRenderMixins should be disactivable as ones can write a component that want to rerender based on the context. (using react-router components for example). I agree that it would be nice to optimize material-ui with PureRenderMixin. I guess there is also some work to do around focus/touch ripple, they generate a lot of useless rerender at the moment. Speaking of something we can see, scrolling a list on a Phone is not really smooth right now. (should not generate rerender or very small one) |
@cgestes I changed focus ripples to only render when the actual component has keyboard focus - d303cac. Hopefully that will help some. I know there are some components that do not require theme variables. I'm thinking that it would be safe for us to optimize those components? I may not be understanding some special requirements of react router that you've mentioned. |
I've been giving this much more thought since I'm in the process of optimizing menus. I think that we should be able to handle context changes pretty easily. It turns out that each component only cares about handful of theme context variables. Which means, each component can track changes to those variables and decide whether or not This can all be handled in a new mixin: const MyComponent = React.createClass({
contextTypes: {
muiTheme: React.PropTypes.object,
},
mixins: [ContextPureRenderMixin],
...
getContextVars() {
return {
fontFamily: this.context.muiTheme.contentFontFamily,
};
}
}); And here's the implmentation for the mixin: module.exports = {
//Save off context vars for future compares in shouldComponentUpdate
componentDidMount() {
this._lastContextVars = this.getContextVars();
},
//Don't update if state, prop, and context are equal
shouldComponentUpdate(nextProps, nextState) {
const currentContextVars = this.getContextVars();
const contextChanged = !shallowEqual(this._lastContextVars, currentContextVars);
//Save off context vars for future compares in shouldComponentUpdate
if (contextChanged) this._lastContextVars = currentContextVars;
return (
!shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState) ||
contextChanged
);
},
}; What do you guys think of this approach? @JAStanton @oliviertassinari @nevir @cgestes |
Yeah sounds like you get the best of both worlds! |
👍 |
What about changes in context only used by childrens (wether mui component On Fri, Jul 31, 2015, 06:52 Ian MacLeod [email protected] wrote:
|
@cgestes The mixin would be added on the children level. So if a child uses context variables to affect its render, then it will add this new mixin if it's pure. Is that what you're asking? |
In the current context impl of react (0.13) Iam not sure that child are On Fri, Jul 31, 2015, 13:56 Hai Nguyen [email protected] wrote:
|
@cgestes The change that I'm proposing would be to implement a new mixin that would account for this. |
@JAStanton @nevir @cgestes I created a PR to address this issue. Hope it makes sense. Please let me know what you think. #1397 |
Following the change @gaearon proposed here facebook/react#2517 and the issue he raised:
Hopefully, Material-ui components are very often leaves of the react tree. We would still have one issue in the case where a material-ui component is not a leaf and the underlying component depend on the context but <Paper> // Rerender
<MyCustomPureRenderComponent> // Don't rerender
<Button /> // Don't rerender
</MyCustomPureRenderComponent>
</Paper> Maybe the solution is to provide an HOC that people have to apply to |
@oliviertassinari if you see the React doc page on context, it seems like the issue you mentioned (and all surrounding issues -- it was quite hard to track them sequentially) resolved to this:
which means that context is accessible to all children in the subtree, and they can opt in as they like. With that being said, we do have most of the things mentioned above implemented today (context-pure mixin, the The recommended way of dealing with I think this can be closed now. |
What would you guys say to adding something like this:
which would block calling
render
if the props or state haven't changed. If added to components that have simple props (i.e. don't take React elements) and have simple state but have heavy render methods (like TextField)?I see this as a potentially huge perf boost when you have a giant form with lots of
TextField
and you're using valueLink. That is, every keystroke of one text field causes all sibling text field's to change to do the state changing.Thoughts?
The text was updated successfully, but these errors were encountered: