Skip to content

Modal: register the drag offset as a non-inherited property - #669

Merged
blvdmitry merged 3 commits into
mainfrom
claude/animation-performance-j38gm8-modal
Sep 12, 2026
Merged

blvdmitry merged 3 commits into
mainfrom
claude/animation-performance-j38gm8-modal

Conversation

@blvdmitry

Copy link
Copy Markdown
Contributor

Summary

Modal drives its swipe-to-close gesture by writing --rs-modal-drag to the modal root on every touchmove frame (throttled by requestAnimationFrame), and the root's transform reads it back. The property itself is the right tool (the transform stays on the compositor), but as an unregistered custom property it inherits, so each write invalidates the computed style of every element inside the modal. On a content-heavy sheet that is the dominant per-frame cost of the gesture, and it lands on the main thread, which is exactly what gets throttled on phones in low-power mode.

This PR registers it with @property { inherits: false } so the update only recalculates the root's own style. No JS or markup changes; nothing else reads the variable.

Measured in headless Chromium on the position: bottom story with 2000 extra rows appended (6008 nodes inside the dialog), timing style.setProperty('--rs-modal-drag') + forced style recalc:

per drag frame
main (inherited custom property) 5.94 ms
this PR (@property, inherits: false) 0.115 ms

Browsers without @property support ignore the rule and keep the previous behavior, same as the existing registrations in ScrollArea and Table.

Related Issue

N/A

Screenshots / Recordings

Simulated a touch drag on a bottom modal in Chromium: the sheet follows the finger (translate(0, 88px) at 88px of drag) and closes on release, same as before.

Notes for Reviewers

  • Modal and Overlay story tests pass locally (23 tests).
  • Related: #667 applies the same fix to the overlay backdrop updated during the drag, and #668 to the ScrollArea thumb.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EAi9QQVSFuJ7Gkf8SUTYJq


Generated by Claude Code

--rs-modal-drag is written to the modal root on every frame of the
swipe-to-close gesture. As an unregistered custom property it inherits,
so each update forced Chromium to recalculate style for every element
of the modal content: measured 5.9ms per frame for a sheet with 6000
nodes. Registering it with @Property { inherits: false } scopes the
recalculation to the root itself (0.1ms per frame on the same sheet).
Browsers without @Property support keep the previous behavior.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAi9QQVSFuJ7Gkf8SUTYJq
@github-actions

github-actions Bot commented Sep 10, 2026 •

Copy link
Copy Markdown

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
Library / JS 50.67 KB (0%) 1.1 s (0%) 106 ms (-47.13% 🔽) 1.2 s
Library / CSS 23.77 KB (0%) 476 ms (0%) 0 ms (+100% 🔺) 476 ms
Theming / JS 7.78 KB (0%) 156 ms (0%) 13 ms (-16.92% 🔽) 168 ms
Theming with a default theme definition / JS 8.69 KB (0%) 174 ms (0%) 15 ms (-0.14% 🔽) 189 ms

@blvdmitry
blvdmitry merged commit 9c58807 into main Sep 12, 2026
2 of 3 checks passed
@blvdmitry
blvdmitry deleted the claude/animation-performance-j38gm8-modal branch September 12, 2026 16:34
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.

2 participants