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

Improve AppProvider and UserProvider rendering perf #5215

Merged
merged 2 commits into from
Jan 13, 2023

Conversation

appden
Copy link
Contributor

@appden appden commented Jan 4, 2023

What, How & Why?

These providers would vend stale state into their context after props changing, which would require another unnecessary full re-render to get updated context values via useEffect hooks. Instead, now state is updated during render so as to immediately restart rendering before stale state is rendered down the context, which is more efficient.

For more information on this approach, please see the Adjusting some state when a props changes section of React beta docs on the "You Might Not Need an Effect" page.

These providers would vend stale state into their context after props changing, which would require another unnecessary full re-render to get updated context values via `useEffect` hooks. Instead, now state is updated during render so as to immediately restart rendering before stale state is rendered down the context, which is more efficient.

For more information on this approach, please see the [Adjusting some state when a props changes](https://beta.reactjs.org/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes) section of React beta docs on the "You Might Not Need an Effect" page.
@cla-bot
Copy link

cla-bot bot commented Jan 4, 2023

Realm welcomes all contributions! The only requirement we have is that, like many other projects, we need to have a Contributor License Agreement (CLA) in place before we can accept any external code. Our own CLA is a modified version of the Apache Software Foundation’s CLA. Our records show that CLA has not been signed by @appden. Please submit your CLA electronically using our Google form so we can accept your submissions. After signing the CLA you can recheck this PR with a @cla-bot check comment. The GitHub usernames you file there will need to match that of your Pull Requests. If you have any questions or cannot file the CLA electronically, make a comment here and we will be happy to help you out.

@appden
Copy link
Contributor Author

appden commented Jan 4, 2023

@cla-bot check

@cla-bot cla-bot bot added the cla: yes label Jan 4, 2023
@cla-bot
Copy link

cla-bot bot commented Jan 4, 2023

The cla-bot has been summoned, and re-checked this pull request!

@bmunkholm
Copy link
Contributor

Hey Scott - lovely to see a PR from you again ;-) Thanks!

@kraenhansen
Copy link
Member

Thanks for your PR! @takameyer which is normally the one reviewing PRs for our React package is OoO until the beginning of next week. I hope we'll get this reviewed shortly thereafter.

Copy link
Contributor

@takameyer takameyer left a comment

Choose a reason for hiding this comment

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

LGTM. Learned something new about React today :) Thanks for the contribution.
Also good catch on the state initializers, as this would call the Realm.App constructor on every render.

Only have one suggestion/question.

}, [configVersion, setApp]);
}

useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this useEffect could also go away and the logic moved under line 51. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for taking a look at this @takameyer! Your asking this made me realize this technically should be useLayoutEffect, so I'll push that update. This is a nuanced one, especially with React's concurrent mode semantics coming to React Native. Refs are typically updated by React right before running layout effects, not during render since a render pass can be thrown away. While it's fine (ish) to update a ref you "own" during render (though that can lead to trouble too), refs you don't own should be updated as side effects because a render can be thrown away with concurrent mode. Also, another benefit here is that if appRef itself changes for some reason, then it'll get updated accordingly. 😀

Copy link
Contributor

Choose a reason for hiding this comment

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

Now that you mention that, I will have to give the generated RealmProvider a look as well. This could most likely also benefit from useLayoutEffect when binding the realmRef.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @takameyer, checking to see if this can be merged. I see a bunch of CI jobs are failing in the same way that appears to be unrelated...

An unexpected error occurred: Input required and not supplied: projectId

Copy link
Contributor

Choose a reason for hiding this comment

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

@appden The fix is now released in 0.4.3

Refs are typically updated by React before running layout effects, so this better matches those semantics.
@takameyer takameyer merged commit d60dfa1 into realm:master Jan 13, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants