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

React excessive rerenders without dedupExchange #425

Closed
ghost opened this issue Sep 11, 2019 · 6 comments
Closed

React excessive rerenders without dedupExchange #425

ghost opened this issue Sep 11, 2019 · 6 comments

Comments

@ghost
Copy link

ghost commented Sep 11, 2019

Describe the bug
Component are render n time where n is the number of components using useQuery.
So if you have 10 components using useQuery, each components are rendered 10 times.

This can be resolved by using dedupExchange.

May be I missed something but is this the normal behavior ? If so, dedupExchange shouldn't always be used.
Thanks for your help !

Expected behavior
Each components should be rendered only one time

Actual behavior
Each components are rendered n time

Additional context
https://codesandbox.io/embed/urql-issue-template-client-mi1dj
Open Console log

@ghost ghost added the bug 🐛 Oh no! A bug or unintented behaviour. label Sep 11, 2019
@JoviDeCroock
Copy link
Collaborator

It is normal that every component will send a fetch request, I'll look into the n*n rerenders. That being said, the dedupExchange is one of the three defaultExchanges. When you make your client it will automatically have dedupExchange, cacheExchange, fetchExchange. Unless you override them.

@ghost
Copy link
Author

ghost commented Sep 11, 2019

Thanks for your comment, that was quick :)

It is indeed a default !
I found this because I tried with https://github.com/FormidableLabs/urql/blob/master/examples/2-using-subscriptions; where the dedupExchange is not used. Bad luck for me.

Thanks again for this great projet :)

@JoviDeCroock
Copy link
Collaborator

No problem, I'll certainly look into why it's received five times but I feel like we'll not be able to do that much about it. Thank you so much for the kind words

@JoviDeCroock
Copy link
Collaborator

I have taken some time to look into this, what happens with the dedupExchange is that we reduce the five requests on the exchange-chain to one.

The rerenders are because every of those five components subscribes to that query, when five requests are sent out and five come in every component will be notified about this since they are all subscribed to that query.

@kitten kitten changed the title React rendering performance issue unless dedupExchange React excessive rerenders without dedupExchange Sep 12, 2019
@kitten kitten added question 🙋 and removed bug 🐛 Oh no! A bug or unintented behaviour. labels Sep 12, 2019
@kitten
Copy link
Member

kitten commented Sep 12, 2019

Hiya 👋 just a small summary before I go ahead and close this.

It's very much expected that each usage of useQuery will trigger its own operation. This is even important because there is no other way for them to signify that they're requesting data.

This is why caching and deduping are important parts of any GraphQL client, or other state management or fetching libraries.

Sometimes we alter the default list of exchanges in examples though to illustrate better what's going on behind the scenes.

It's also worth noting that performance issues and excessive rerenders are two very different problems in React. Excessive rerenders aren't inherently bad as long as they're quick. Performance issues do occur when the renders themselves become exceedingly expensive. That's why libraries commonly avoid unnecessary rerenders wherever possible, to make it less likely that performance becomes an issue.

For us there are two parts to this: we aggressively avoid unnecessary updates in our hooks and ensure that the initial render reflects the data that is already cached. And we have internal logic that is not React-specific like the dedupExchange that ensure that we don't do duplicate work internally.

Hope this makes sense 👍 for questions we also have our Spectrum community where we're able to answer questions in more detail, since it's more of a chat. ☀️

@kitten kitten closed this as completed Sep 12, 2019
@ghost
Copy link
Author

ghost commented Sep 12, 2019

Thanks for your detailed explaination.
I see how this behavior makes sence since it's the exact same query and there is caching, the request only sent once and when the response is received it will not know who needs it.

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

No branches or pull requests

2 participants