[React Doctor] Marked 7 scroll and touchstart listeners as passive#432
Open
github-actions[bot] wants to merge 1 commit into
Open
[React Doctor] Marked 7 scroll and touchstart listeners as passive#432github-actions[bot] wants to merge 1 commit into
github-actions[bot] wants to merge 1 commit into
Conversation
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
4 tasks
Contributor
There was a problem hiding this comment.
Additional Suggestions:
- Event listener for touchstart is added with { capture: true, passive: true } but removed with only { capture: true }, causing the listener to not be properly removed
- The visualViewport scroll event listener is registered with { passive: true } but removed without the passive option, preventing proper cleanup and causing a memory leak
- Missing { passive: true } option in removeEventListener causes visualViewport scroll listener to not be properly removed, creating a memory leak
- addEventListener and removeEventListener options mismatch causes memory leak in event listener cleanup
- visualViewport scroll event listener is not properly removed due to mismatched addEventListener/removeEventListener options, causing a memory leak
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.
Marked 7 scroll and touchstart listeners as
{ passive: true }— unblocks main-thread scrolling on these handlers, none of which callpreventDefault()Browsers treat
scroll/touchstartlisteners as blocking by default — the compositor waits on each event until JS confirms it isn't going to callpreventDefault(). All 7 handlers here are pure observers (re-measuring viewport, syncing positions, dismissing overlays); none gate scrolling. Flipping them to{ passive: true }lets the browser scroll without that wait.Changes
apps/website/components/mobile-demo-animation.tsx:306—client-passive-event-listeners:visualViewportscroll →{ passive: true }(handler ismeasureElementPositions, pure measurement)apps/website/components/ui/scrollable.tsx:46—client-passive-event-listeners: element scroll →{ passive: true }(updateScrollbaronly sets state fromscrollHeight/clientHeight)packages/react-grab/src/core/index.tsx:2893—client-passive-event-listeners: mergepassive: trueinto the existing{ signal }options objectpackages/react-grab/src/components/toolbar/index.tsx:520—client-passive-event-listeners:visualViewportscroll →{ passive: true }(handleResizeschedules a recalc, nopreventDefault)packages/react-grab/src/components/selection-label/index.tsx:152—client-passive-event-listeners:visualViewportscroll →{ passive: true }(handleViewportChangejust bumps a signal)packages/react-grab/src/utils/create-anchored-dropdown.ts:97—client-passive-event-listeners:visualViewportscroll →{ passive: true }(handleViewportChangeis a batched setter)packages/react-grab/src/utils/register-overlay-dismiss.ts:52—client-passive-event-listeners: mergepassive: trueinto the existing{ capture: true }options (handleClickOutsideonly callsonDismiss)Note
Low Risk
Observer-only listeners with no preventDefault; passive flag is safe and limits scope to scroll performance.
Overview
Marks seven
scrollandtouchstartlisteners as{ passive: true }across the marketing site andreact-grabso the browser can scroll without waiting on JS that never callspreventDefault().Website:
visualViewportscroll in the mobile demo (re-measure layout) and elementscrollinScrollable(custom scrollbar sync).Library:
visualViewportscroll on the selection label, toolbar, anchored dropdowns, and core overlay (viewport/version sync);touchstarton overlay dismiss is passive alongside existing capture, whilemousedownstays non-passive where needed.Behavior is unchanged—these handlers only measure, reposition, or dismiss.
Reviewed by Cursor Bugbot for commit ef5d264. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Marked 7 scroll and touchstart listeners as passive to remove main-thread blocking during scroll. Improves scroll responsiveness without behavior changes, since none of these handlers call preventDefault.
visualViewportscroll handlers (toolbar, selection label, mobile demo, dropdown anchoring, core init).scrollinScrollable.signaland{ capture: true }(overlay dismisstouchstart).Written for commit ef5d264. Summary will update on new commits.