-
-
Notifications
You must be signed in to change notification settings - Fork 180
fix(Presence): optimize animation detection for large DOMs #1924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: e50b5a3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
built with Refined Cloudflare Pages Action⚡ Cloudflare Pages Deployment
|
| * the entire DOM tree, which is extremely slow with large DOMs. | ||
| * | ||
| * Instead, we only set userSelect on the dialog content itself. | ||
| * This is a minor UX tradeoff (text selection can technically overflow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say this isn't a minor tradeoff since the whole idea of this utility is to prevent this behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right - I understated the impact.
I've reverted the TextSelectionLayer change. The PR now only includes:
- Presence layer animation caching - TTL-based caching for getAnimationName() and style snapshots to prevent layout thrashing
- CSS containment - contain: layout style paint on floating content elements
I also discovered that preventOverflowTextSelection={false} already exists as a prop on Dialog/Popover content. For apps with large DOM trees where the body style modification causes performance issues, users can opt-out by setting this prop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! Will give this a review, appreciate you looking into this.
This PR addresses significant performance issues when opening/closing
dialogs, popovers, and menus in applications with large DOM trees
(e.g., chat apps with hundreds of messages).
Changes:
1. **Presence layer animation caching** (`presence.svelte.ts`):
- Added TTL-based caching for `getAnimationName()` to reduce
redundant `getComputedStyle()` calls from 4+ per animation
cycle down to 1
- Changed `styles` state from live `CSSStyleDeclaration` to a
snapshot object `{ display, animationName }` to prevent
layout thrashing when accessing style properties
2. **CSS containment** (`dialog.svelte.ts`, `popover.svelte.ts`,
`menu.svelte.ts`):
- Added `contain: layout style paint` to floating content
elements to isolate style/layout calculations from the
rest of the page
These changes dramatically improve animation performance in apps with
large DOMs, reducing dialog open/close blocking time from ~150ms to
~15ms in tested scenarios.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
31b5c96 to
70827fe
Compare
This PR addresses significant performance issues when opening/closing dialogs, popovers, and menus in applications with large DOM trees (e.g., chat apps with hundreds of messages).
Changes:
Presence layer animation caching (
presence.svelte.ts):getAnimationName()to reduce redundantgetComputedStyle()calls from 4+ per animation cycle down to 1stylesstate from liveCSSStyleDeclarationto a snapshot object{ display, animationName }to prevent layout thrashing when accessing style propertiesCSS containment (
dialog.svelte.ts,popover.svelte.ts,menu.svelte.ts):contain: layout style paintto floating content elements to isolate style/layout calculations from the rest of the pageTextSelectionLayer optimization (
use-text-selection-layer.svelte.ts):document.bodystyle modifications that were triggering full DOM style recalculations on every pointerdownuserSelecton the dialog content itselfThese changes dramatically improve animation performance in apps with large DOMs, reducing dialog open/close blocking time from ~150ms to ~15ms in tested scenarios.