Skip to content

fix(hooks): eliminate scroll jitter when prepending items at bottom#2095

Merged
naqvitalha merged 2 commits intoShopify:mainfrom
Hector-Zhuang:fix/2094
Feb 11, 2026
Merged

fix(hooks): eliminate scroll jitter when prepending items at bottom#2095
naqvitalha merged 2 commits intoShopify:mainfrom
Hector-Zhuang:fix/2094

Conversation

@Hector-Zhuang
Copy link
Contributor

Description

Fixes #2094

This pull request addresses the jittery scroll animation on iOS when items are prepended to the top of the list while the list is positioned at the bottom.

The Problem

When items are added to the top, the LayoutManager immediately calculates a new scroll offset to "lock" the current visible messages in place so they don't jump.

Simultaneously, because animateAutoScrollToBottom is enabled and the list is at the bottom, the component triggers a scrollToEnd({ animated: true }).

The Fix

I have modified useBoundDetection to detect when the list is already anchored at the bottom (via isNearBottom.current).

  • When new data is added at the top (prepend), the PR ensures that the scroll synchronization happens silently (animated: false) to avoid clashing with the coordinate recomputation.
  • Smooth animations are preserved for regular "bottom-up" updates (append) where no coordinate shift conflict exists.

Reviewers’ hat-rack 🎩

  • isNearBottom.current reliability: Verify this ref accurately tracks the bottom state during rapid data updates.
  • Prepend vs Append: Ensure that only top-insertions skip the animation, while new incoming messages at the bottom still animate smoothly.
  • Test with the provided Expo Snack: https://snack.expo.dev/@hectorton/cranky-red-graham-crackers
  • Verify no regression in standard Vertical/Horizontal lists without maintainVisibleContentPosition.

Screenshots or videos (if needed)

Reproduction Video (from #2094):
https://github.com/user-attachments/assets/11cc145c-f65b-4e34-8585-961a455a27bc

Fixed Behavior:
The list now remain stable when items are added to the top, and smoothly scrolls only when new items are added to the bottom.

@naqvitalha
Copy link
Collaborator

naqvitalha commented Feb 10, 2026

Thanks for the PR!

There's actually an existing signal that might fit this use case perfectly: recyclerViewManager.ignoreScrollEvents. It's set to true for ~100ms during offset corrections (i.e., when a prepend triggers a scroll adjustment), which is exactly the window where the animation conflict happens.

So instead of the new ref, this should work as a one-line change in runAutoScrollToBottomCheck:

scrollViewRef.current?.scrollToEnd({
  animated: shouldAnimate && !recyclerViewManager.ignoreScrollEvents,
});

This way animation is only skipped when an offset correction is in progress, and normal appends still animate smoothly. Could you try this out and see if it fixes the jitter in your repro?

@naqvitalha
Copy link
Collaborator

Also please sign the CLA

@Hector-Zhuang
Copy link
Contributor Author

Thanks. This fix also works. i've updated this branch.

Copy link
Collaborator

@naqvitalha naqvitalha left a comment

Choose a reason for hiding this comment

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

Looks good. If you can sign the CLA we can merge it.

@Hector-Zhuang
Copy link
Contributor Author

Just signed the CLA. Thx!

@naqvitalha naqvitalha enabled auto-merge (squash) February 11, 2026 01:09
@naqvitalha naqvitalha merged commit 5a15a80 into Shopify:main Feb 11, 2026
11 checks passed
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.

Jittery scroll animation when prepending items with startRenderingFromBottom and animateAutoScrollToBottom enabled on iOS

2 participants