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

Fix double render on selector change #825

Closed
wants to merge 4 commits into from
Closed

Fix double render on selector change #825

wants to merge 4 commits into from

Conversation

salvoravida
Copy link
Contributor

@salvoravida salvoravida commented Jan 10, 2021

This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jan 10, 2021
@salvoravida salvoravida changed the title Fix/double render selector change Fix double render on selector change Jan 10, 2021
@drarmstr drarmstr self-assigned this Jan 11, 2021
Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

@drarmstr has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

@drarmstr drarmstr left a comment

Choose a reason for hiding this comment

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

Thank you so much for continuing to improve this optimization!

Could you generate a unit test that helps confirm the situation where this change eliminates an extra render? You can see an example for such test with "Updating with same value doesn't rerender" test in https://github.com/facebookexperimental/Recoil/blob/master/src/recoil_values/__tests__/Recoil_atom-test.js

Note that I updated the unit tests from importing #820 so compensate for that fix in removing the extra render when the GK is set which you should hopefully see when that merges.

@drarmstr
Copy link
Contributor

@salvoravida - #820 has now been merged. Notice in the update that it was tweaked to be behind the GK feature flag check and the unit tests were updated. We'll see if that causes any issues with nightly testing.. But, from those examples hopefully you can see how the unit testing works. Could you update this PR with an example test to help clarify the situations it affects and catch potential regressions?

@drarmstr drarmstr added the pending Pending more information or user action label Feb 3, 2021
@facebook-github-bot
Copy link
Contributor

@salvoravida has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@salvoravida has updated the pull request. You must reimport the pull request before landing.

@salvoravida
Copy link
Contributor Author

Hi @drarmstr, i have just rebased the pr on last master commit, moreover i added the test for this case.
it should also fix another test with one less re-render that is a similar case: selector unmounting

@drarmstr
Copy link
Contributor

@salvoravida - Ah, yes, excellent! Thank you for the test! I'll try to review this next week then. With #952 landing now we can start to open up this optimization for our internal testing again.

@facebook-github-bot
Copy link
Contributor

@drarmstr has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@drarmstr
Copy link
Contributor

@salvoravida - I had a chance to go over the test and it looks good. However, I'm still not clear on what change the fix is supposed to do. It looks like the test works both with and without the code changes in Recoil_Hooks.js.

@salvoravida
Copy link
Contributor Author

@salvoravida - I had a chance to go over the test and it looks good. However, I'm still not clear on what change the fix is supposed to do. It looks like the test works both with and without the code changes in Recoil_Hooks.js.

Hi @drarmstr (as first comment)
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

about tests:

With this pr(my mod on Recoil_Hooks)
Test Suites: 34 passed, 34 total
Tests: 2 skipped, 811 passed, 813 total

Without:
Test Suites: 1 failed, 33 passed, 34 total
Tests: 2 failed, 2 skipped, 809 passed, 813 total

● Components unsubscribe from atoms when rendered without using them [recoil_suppress_rerender_in_callback]

expect(jest.fn()).toHaveBeenCalledTimes(expected)

Expected number of calls: 3
Received number of calls: 4

  825 |     act(() => toggleSwitch());
  826 |     expect(container.textContent).toEqual('0');
> 827 |     expect(Component).toHaveBeenCalledTimes(baseCalls + 3);

● Components re-render only one time if selectorFamily changed [recoil_suppress_rerender_in_callback]

expect(jest.fn()).toHaveBeenCalledTimes(expected)

Expected number of calls: 2
Received number of calls: 3

  1758 | 
  1759 |     expect(container.textContent).toEqual('1');
> 1760 |     expect(Component).toHaveBeenCalledTimes(baseCalls + 2);

Are you sure you have tested the OSS version? may have some problems with flags?

@drarmstr
Copy link
Contributor

drarmstr commented Apr 26, 2021 via email

@salvoravida
Copy link
Contributor Author

@drarmstr note that Suspence pr is not merged on my branch.

@salvoravida
Copy link
Contributor Author

salvoravida commented May 5, 2021

@drarmstr note that Suspence pr is not merged on my branch.

Hi @drarmstr i tested this PR over the Suspense one. it seems the suspense one has the same effect on the test.
Anyway, there is one extra optimization in one test with this pr:
'Components unsubscribe from atoms when rendered without using them',

image

it allows one render less on legacy mode, and component unsubscribe.

@drarmstr
Copy link
Contributor

drarmstr commented May 6, 2021

Ah, good; glad the additional Suspense fix explains the discrepancy. Ok, I'll test again with that test as soon as I have a chance. Thanks!

@drarmstr drarmstr removed the pending Pending more information or user action label Dec 9, 2021
drarmstr pushed a commit to drarmstr/Recoil that referenced this pull request Dec 16, 2021
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental#825

Reviewed By: bezi

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: 0c741fc5cda1a8cadfd01660242acc5e51f1d6e1
drarmstr pushed a commit to drarmstr/Recoil that referenced this pull request Dec 16, 2021
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental#825

Reviewed By: bezi

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: b317c6095df400546f3623c8f97530875f667648
drarmstr pushed a commit to drarmstr/Recoil that referenced this pull request Dec 16, 2021
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental#825

Reviewed By: bezi

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: c6d38d603dded9f4fc61d657d7444f2d3edc751f
drarmstr pushed a commit to drarmstr/Recoil that referenced this pull request Dec 16, 2021
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental#825

Reviewed By: bezi

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: 07b1dc3a9eb970693fe46673781f2df150f6ef25
drarmstr pushed a commit to drarmstr/Recoil that referenced this pull request Dec 16, 2021
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental#825

Reviewed By: bezi

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: 92d4e52514259059ac862fef26ca8ea09c3f50c7
drarmstr pushed a commit to drarmstr/Recoil that referenced this pull request Dec 16, 2021
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental#825

Reviewed By: bezi

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: 0eac0fb24292ae4d07090c661933e8b27c499819
@drarmstr
Copy link
Contributor

Finally got around to validating and landing this optimization while working on the latest rendering modes. Thanks again @salvoravida.

AlexGuz23 pushed a commit to AlexGuz23/Recoil that referenced this pull request Nov 3, 2022
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental/Recoil#825

Reviewed By: habond

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: 8fa0491bb6bffb48287a71a619d502f62ce321cb
snipershooter0701 pushed a commit to snipershooter0701/Recoil that referenced this pull request Mar 5, 2023
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental/Recoil#825

Reviewed By: habond

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: 8fa0491bb6bffb48287a71a619d502f62ce321cb
eagle2722 added a commit to eagle2722/Recoil that referenced this pull request Sep 21, 2024
Summary:
This pr just set the current value before store subscribe/resubscribe
This prevent double rendering when using selectorFamily in child nodes, controlled by parent props.

Issue CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-issue-fhbxk

Fixed CodeSandbox:
https://codesandbox.io/s/recoil-legacy-selector-change-double-render-fixed-feub8

Pull Request resolved: facebookexperimental/Recoil#825

Reviewed By: habond

Differential Revision: D25873280

Pulled By: drarmstr

fbshipit-source-id: 8fa0491bb6bffb48287a71a619d502f62ce321cb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants