try(pinch): Wave 2 — stepped layout-prop styles (scroll-source consolidation reverted)#30
Closed
anton-patrushev wants to merge 2 commits into
Closed
Conversation
Three Android-Fabric-targeted perf/correctness fixes: 1. CalendarBody's horizontalLinesWrapperStyle (top/height layout props) and TimelineBoard's per-BodyItem horizontalLinesWrapperStyle (height + transform) now read a STEPPED zoomScale (10% increments via useDerivedValue) instead of the raw SV. On Fabric Android, parallel layout-prop animated styles commit via Yoga on a separate path from the inner-scale's transform commit; two paths racing per frame can land out of order, producing a one-frame visual mismatch. Stepping reduces the commit cadence ~10x with no visible artifact (10% step transitions in line position during smooth pinch are invisible). 2. Drop JS-thread _onScroll. Replace with a useAnimatedReaction on scrollOffsetLive that writes offsetY on the UI thread. Two sources writing to offsetY from different threads (JS onScroll alongside the worklet-event registration backing scrollOffsetLive) was an Android Fabric race source — the bridge marshalled events twice and the two paths could converge to different values mid-pinch.
… platforms The useAnimatedReaction-on-scrollOffsetLive approach for driving offsetY worked in theory but broke scroll in practice on both platforms. The library uses react-native-gesture-handler's ScrollView (not RN's stock), and dropping the JS onScroll prop appears to disconnect the native scroll-event emitter from useScrollViewOffset's worklet handler on the gh-ScrollView + Fabric path — scrollOffsetLive stays at 0, offsetY never updates, and downstream library state breaks. Android exhibits this as 'scroll dead even before pinch'; iOS exhibits as 'scroll sometimes stuck after pinch' (the lock state-machine reads stale live offset and the post-pinch reaction never re-syncs). Keep the Wave 2 stepped layout-prop changes — those were the actual perf win and don't touch scroll.
Owner
Author
|
Superseded by platform-split fix graduated into PR #28. Closing. |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Experimental Wave 2 (revised) — Android pinch hardening, layered on Wave 1 (PR #29). Base: `try/pinch-drift-absorb-android` (Wave 1).
What's in / what's out
In (kept):
Out (reverted in this revision):
Consolidate scroll source: drop JS `_onScroll`, drive `offsetY` from `scrollOffsetLive` reaction— broke scroll on both platforms. The library uses `react-native-gesture-handler`'s ScrollView (not RN's); dropping the JS `onScroll` prop apparently disconnects the native scroll-event emitter from `useScrollViewOffset`'s worklet handler on the gh-ScrollView + Fabric path. `scrollOffsetLive` stays at 0, `offsetY` never updates. Android exhibited as "scroll dead even before pinch"; iOS as "scroll sometimes stuck after pinch."Test plan (revised)