-
-
Notifications
You must be signed in to change notification settings - Fork 234
Open
Description
🐛 Bug report
Screen.Recording.2025-12-21.at.00.07.54.mov
when using a popper-based component (popover in my case) the use of css variables leads to very expensive css recomputations when there's a lot of content in the popover, that add up with the floating-ui's own reflows, making the overall experience very sluggish
💥 Steps to reproduce
- open repro below
- open the popover
- scroll the page down
- notice how sluggish the popover position updates are
💻 Link to reproduction
https://stackblitz.com/edit/ipjqylaw?file=src%2FPopover.tsx
🧐 Expected behavior
the popover updates smoothly
🧭 Possible Solution
below are the patches i had to apply for the scrolling to get smooth in my app:
simply removing the use of css variables (and a child z-index computation) already improves it a lot:
@@ -247,8 +247,7 @@ function getPlacementImpl(referenceOrVirtual, floating, opts = {}) {
const win = getWindow(floating);
const x = roundByDpr(win, pos.x);
const y = roundByDpr(win, pos.y);
- floating.style.setProperty("--x", `${x}px`);
- floating.style.setProperty("--y", `${y}px`);
+ floating.style.transform = `translate3d(${x}px, ${y}px, 0)`
if (options.hideWhenDetached) {
const isHidden = pos.middlewareData.hide?.referenceHidden;
if (isHidden) {
@@ -260,10 +259,6 @@ function getPlacementImpl(referenceOrVirtual, floating, opts = {}) {
}
}
const contentEl = floating.firstElementChild;
- if (contentEl) {
- const styles = getComputedStyle(contentEl);
- floating.style.setProperty("--z-index", styles.zIndex);
- }
};
@@ -336,7 +332,6 @@ function getPlacementStyles(options = {}) {
top: "0px",
left: "0px",
// move off-screen if placement is not defined
- transform: placement ? "translate3d(var(--x), var(--y), 0)" : "translate3d(0, -100vh, 0)",
zIndex: "var(--z-index)"
}
};
i dont need
--z-indexso i removed it, butgetComputedStyle(contentEl)should probably be inside a raf.
then made the getSizeMiddleware optional:
@@ -189,6 +189,7 @@ function getShiftMiddleware(opts) {
});
}
function getSizeMiddleware(opts) {
+ if (opts.noSizeMiddleware) return;
return size({
padding: opts.overflowPadding,
and now scrolling is finally smooth:
Screen.Recording.2025-12-21.at.00.15.40.mov
🌍 System information
| Software | Version(s) |
|---|---|
| Zag Version | 1.31.1 |
| Browser | Chrome 142 |
| Operating System | macOS |
📝 Additional information
Metadata
Metadata
Assignees
Labels
No labels