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

[WIP] Avoid forcing useless renders #1569

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft

Conversation

paultranvan
Copy link
Contributor

@paultranvan paultranvan commented Dec 5, 2024

Each time a useQuery is made, it is saved as a listener in redux, through the useSelector hook. We provide the result of getQueryFromState to this hook to evaluate whether or not the state changed. By default, this evaluation is a referential equality check. See https://react-redux.js.org/api/hooks#useselector :

When an action is dispatched, useSelector() will do a reference comparison of the previous selector result value and the current result value. If they are different, the component will be forced to re-render.

The issue here is that the getQueryFromState function always return a new object : https://github.com/cozy/cozy-client/blob/master/packages/cozy-client/src/CozyClient.js#L1428
Therefore, the reference comparison will never be true.

And because the dispatch will make the evaluation of all listeners, it means any query will force the re-render to all components having a useQuery, leading to performance issues.

See this performance check, measured on Cozy Drive :

Before

Capture d’écran du 2024-12-03 15-49-34

After

Capture d’écran du 2024-12-04 11-09-34

@@ -1193,7 +1193,7 @@ client.query(Q('io.cozy.bills'))`)
if (queryDef instanceof QueryDefinition) {
definitions.push(queryDef)
} else {
documents.push(queryDef)
documents.push(doc)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this part of the fix? I don't understand the impact compared to the previous implementation

We used to hydrate any document with the relationships existing in the
provided schema, even though the relationship does not exist on the
document. We now hydrate only if the relationship is set in the
document.
Note we can still force the hydratation through a `forceHydration`
option, to ease migrations on apps with many relations.

BREAKING CHANGE: the relationship hydration is made only if the
relationship exists in the document, so the developer should not assume
a `document.relationshipName` is always defined, anymore.
As an alternative, it is now possible to pass `forceHydration` on
cozy-client options to ease migration.
However, please not this has performance impact, as it forces
extra-check on store queries evaluation.
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

Successfully merging this pull request may close these issues.

2 participants