-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[OPIK-8005] [FE] perf: cut per-cell store subscriptions 5x, skip no-op dataset hydration #7934
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
Open
Nimrod007
wants to merge
2
commits into
main
Choose a base branch
from
Nimrod007/OPIK-8005/playground-perf-quick-wins
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+53
−35
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale media fetch overwrites new dataset
The no-media early-return path resets the shared
cancelledRef.currenttofalsewithout installing a replacement cleanup, so an earlierhydrateItemscontinuation can pass its post-awaitcancellation check and callsetHydratedItemson the new array, overwriting it with stale data or updating state after unmount — should we use a generation-specific cancellation token, or install cleanup on every effect path?Want Baz to fix this for you? Activate Fixer
Other fix methods
Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit fb17f8e addressed this comment by replacing the shared cancellation ref with an effect-scoped cancellation token. Previous async hydrations are invalidated by cleanup before a new effect run, including no-media early returns and unmounts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct catch, and worth being precise about why it matters: this was a latent flaw that the no-media early return turned into a dangerous one.
cancelledRefis one ref shared across every effect run, and the effect body reset it tofalseon entry. React runs the previous run cleanup before the next body, so the sequence is: run 1 starts hydrating dataset A and installs cleanup -> dataset changes -> cleanup setscancelled = true-> run 2 enters and resets it tofalse, un-cancelling run 1 still-pending loop -> run 1 continuation passes its post-awaitcheck and callssetHydratedItemson the new array.Before this PR the only early return sat after
setHydratedItems([]), so that stale continuationprev.map()ran over an empty array and produced nothing. Harmless, which is why it went unnoticed. The early return I added sits aftersetHydratedItems(datasetItems)with a populated array, so the same continuation writes dataset A data into dataset B array at a positional index — silent cross-dataset corruption, reachable by switching dataset or page size while a media-bearing dataset is still hydrating.Fixed in fb17f8e by taking your second suggestion rather than a generation token: the flag is now scoped to each effect run (
let cancelled = false) instead of being a shared ref. Each run observes only its own flag, so early-returning without installing cleanup cannot resurrect an older run loop, and no path needs its own cleanup to stay correct. That also fixes the pre-existing empty-dataset path and the setState-after-unmount case, and drops theuseRefimport.Preferred it over a generation counter because it removes the shared mutable state entirely rather than versioning it, so the whole class of bug goes away instead of being guarded against.
One thing I did not do: there is no regression test. Reproducing it needs an in-flight media fetch interleaved with a dataset swap, and the hook has no existing test harness. The fix is reasoned against React cleanup ordering, not proven by test, so it is worth a human eye.