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

Prevent onSelectionChange from affecting selection tool performance #1298

Merged
merged 1 commit into from
Nov 24, 2022

Conversation

axelboc
Copy link
Contributor

@axelboc axelboc commented Nov 24, 2022

onSelectionChange was called on every pointer move event, so it had the potential to affect the performance of the selection tool. I'm moving the call inside a useEffect so that it happens asynchronously, after the RAF selection state is updated and after the selection tool and its render prop have had time to re-render.

@axelboc axelboc force-pushed the selection-refacto-2 branch 2 times, most recently from bbdeda9 to 08ce404 Compare November 24, 2022 09:51
@axelboc axelboc requested a review from loichuder November 24, 2022 09:52
@loichuder
Copy link
Member

loichuder commented Nov 24, 2022

Sorry for my ignorance but I don't understand how this improves performance 😅

With this implementation:

  • On pointer move, the state of SelectionTool changes, triggering a rerender.
  • The rerender of SelectionTool triggers the execution of the useEffect and therefore of onSelectionChange.

Therefore, in effect, onSelectionChange is still called on every pointer move event ?

Base automatically changed from selection-refacto-1 to main November 24, 2022 11:14
@axelboc
Copy link
Contributor Author

axelboc commented Nov 24, 2022

Kinda. onSelectionChange is now called asynchronously:

  1. outside of the current animation frame thanks to active selection's useRafState, which means that if the browser is busy and a selection state update is skipped, onSelectionChange is no longer called either;
  2. on the next render thanks to useEffect, which means that if the consumer sets a state in onSelectionChange, the parent component gets re-rendered after the active selection (which is the most time-sensitive thing) instead of before. And since I use useEffect and not useLayoutEffect, the re-rendered active selection has time to actually be painted by the browser, which maximises the perceived responsiveness of the selection for the user.

@axelboc axelboc force-pushed the selection-refacto-2 branch from 08ce404 to 89f5dac Compare November 24, 2022 12:54
@axelboc axelboc merged commit d09aa32 into main Nov 24, 2022
@axelboc axelboc deleted the selection-refacto-2 branch November 24, 2022 13:19
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