Skip to content

Build the scroll event payload in one JNI call - #59714

Open
tomekzaw wants to merge 1 commit into
react:mainfrom
tomekzaw:scroll-event-payload-one-call
Open

tomekzaw wants to merge 1 commit into
react:mainfrom
tomekzaw:scroll-event-payload-one-call

Conversation

@tomekzaw

Copy link
Copy Markdown
Contributor

Summary:

ScrollEvent.getEventData() builds the payload one field at a time from Java. It creates 6 WritableNativeMaps (one initHybrid call each) and makes 20 put* calls, so each scroll event costs 26 calls into C++. Scroll events are sent up to once per frame on the UI thread while scrolling.

Now Kotlin fills a DoubleArray with the 9 numeric fields and makes one call, ScrollEventHelper.nativeCreateScrollPayload. C++ builds the whole payload as one WritableNativeMap. This is the same approach as the touch payload in #59554. The payload has the same keys and values as before.

Changelog:

[ANDROID] [CHANGED] - Build the scroll event payload in one JNI call

Test Plan:

Time per getEventData() call (timer around it in Event.dispatchModern) on a Playground ScrollView with 300 rows, scrollEventThrottle={16} and an onScroll handler, swiped up and down with adb shell input swipe for the whole window:

Galaxy A16 Pixel 9a OPPO CPH2269 moto g57 power
ScrollEvent.getEventData() 131.31 µs → 72.75 µs (−45%) 60.38 µs → 35.54 µs (−41%) 110.85 µs → 54.23 µs (−51%) 38.15 µs → 23.03 µs (−40%)

For comparison, an unchanged path timed in the same runs (UpdateState mount items) moved by 0–6%.

Setup:

  • Release RNTester (./gradlew :packages:rn-tester:android:app:assembleRelease -PreactNativeArchitectures=arm64-v8a, R8 on) with default feature flags, compiled with cmd package compile -m speed.
  • Temporary timing probes, not part of this PR, and a Playground scenario opened by deep link.
  • Each run is a fresh process: a 12 s window after the scenario starts, reported as the median of its samples. Per phone, one discarded run of each build, then 8 A/B/B/A cycles of main and this PR (16 processes per build).
  • Each figure is the median of the 16 processes. All four changes have 95% bootstrap confidence intervals that exclude zero.
  • The Galaxy A16, Pixel 9a and moto g57 power run Android 16. The OPPO CPH2269 runs Android 11.

Payload check: on the moto g57 power, a Playground screen shows the nativeEvent of the last scroll event as JSON. After the same swipe on main and with this PR, the keys match, and so do contentInset, contentOffset, contentSize, layoutMeasurement, target and responderIgnoreScroll. Only the time-dependent fields (velocity and the timestamp) differ.

Checks:

  • yarn cxx-api-build, then yarn cxx-api-validate (Doxygen 1.16.1): all 12 snapshots match. The new header adds ScrollEventHelper to the 4 Android snapshots.
  • yarn format-check-cpp and yarn format-check-kotlin pass.

Pointer events build their payloads the same way, but they're off by default (dispatchPointerEvents), so I left them out.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@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 Oct 31, 2026
@facebook-github-tools facebook-github-tools Bot added p: Software Mansion Partner: Software Mansion Partner labels Oct 31, 2026
@tomekzaw
tomekzaw marked this pull request as ready for review October 31, 2026 08:38
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 31, 2026

This branch has not been deployed

No deployments
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: Software Mansion Partner: Software Mansion 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.

1 participant