Skip to content

Fix maintainVisibleContentPosition with rapid data updates (#53542) - #57955

Open
kulkarni-rohan wants to merge 1 commit into
react:mainfrom
kulkarni-rohan:fix/53542-rapid-mvcp
Open

Fix maintainVisibleContentPosition with rapid data updates (#53542)#57955
kulkarni-rohan wants to merge 1 commit into
react:mainfrom
kulkarni-rohan:fix/53542-rapid-mvcp

Conversation

@kulkarni-rohan

Copy link
Copy Markdown
Contributor

Fixes #53542

Summary:

Problem: maintainVisibleContentPosition fails when FlatList data is updated rapidly with prepends in quick succession (e.g., chat receiving messages). After 2 prepends before native scroll drains, render window stays frozen, onViewableItemsChanged suppressed, onEndReached never fires.

Root cause: pendingScrollUpdateCount assumption is structurally unsound – it increments by 1 per prepend in getDerivedStateFromProps (0→1→2) but native scroll events are dispatched as unique events that coalesce. Verified in C++:

  • ScrollViewEventEmitter.cpp:13onScroll dispatched with dispatchUniqueEvent("scroll", ...)
  • EventQueue.cpp:29-50 – unique event whose target+type matches existing replaces in place (line 49) instead of appending
    So N scroll events emitted before queue flush deliver exactly 1 to JS. Single coalesced event drains 2→1 leaving blocked. Also leak when JS predicate fires (old key found at new index) but native declines to adjust (tag recycled, view deleted, delta ≤0.5, clamped).

Fix (1 file, 2 lines core): Clamp pending to at most 1 and drain to 0 on any scroll:

  • pendingScrollUpdateCount: 1 instead of prev+1 – prevents accumulation during rapid prepends
  • setState({pendingScrollUpdateCount: 0}) instead of -1 – single coalesced scroll unblocks

This turns "stuck at N" into unblocked after next scroll, fixing frozen window / viewability / onEndReached for rapid updates. For leak path where native declines (no scroll ever), flag would still be stranded at 1 – addressed by boolean rename + escape hatch in follow-up, but this PR already strictly improves and matches existing tests that drain 0→1→0.

Changelog:

[GENERAL] [FIXED] - Fix maintainVisibleContentPosition with rapid data updates (#53542)

Test Plan:

Jest (VirtualizedList):

yarn jest --watchman=false packages/virtualized-lists/Lists/__tests__/VirtualizedList-test.js --no-coverage --ci
# Before: new coalesced test fails with pending 1
# After: 83 passed (82 existing + 1 new rapid prepends with coalesced scroll), 1 skipped, 59 snapshots

New test ( regression for #53542 ):

  • Simulates 2 rapid prepends WITHOUT intermediate scroll (5 + 3 items)
  • Only 1 coalesced scroll event (delta 8*ITEM_HEIGHT)
  • Asserts pendingScrollUpdateCount === 0 (fails on main with 1) and firstVisibleItemKey not null

Existing MVCP tests still pass:

  • handles maintainVisibleContentPosition
  • handles multiple rapid prepends (separate scroll per prepend)
  • delta stays bounded
  • minIndexForVisible >0 and inverted

Lint:

yarn lint
# Done (max-warnings 0)

Closes #53542

Fixes react#53542 where rapid prepends with coalesced native scroll events leave pendingScrollUpdateCount stuck, freezing render window.

Root cause: pendingScrollUpdateCount increments by 1 per prepend (0->1->2) but EventQueue coalesces N scroll events into 1 via dispatchUniqueEvent (ScrollViewEventEmitter.cpp:13 + EventQueue.cpp:29-50 replaces in place), so single scroll drains 2->1 leaving blocked. Also leak when JS predicate fires but native declines (tag recycled, delta<=0.5, clamped).

Fix: Clamp pending to 1 (not accumulate) and drain to 0 on any scroll, so single coalesced event unblocks. Prevents frozen window, suppressed onViewableItemsChanged and onEndReached.

[GENERAL] [FIXED] - Fix maintainVisibleContentPosition with rapid data updates (react#53542)
@meta-cla meta-cla 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 Aug 13, 2026
@facebook-github-tools facebook-github-tools Bot added p: Facebook Partner: Facebook Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. labels Aug 13, 2026
@meta-codesync

meta-codesync Bot commented Aug 13, 2026

Copy link
Copy Markdown

@fabriziocucci has imported this pull request. If you are a Meta employee, you can view this in D115907610.

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. p: Facebook Partner: Facebook Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

maintainVisibleContentPosition fails with rapid FlatList data updates

1 participant