[useScrollLock] Reduce style recalculation with classic scrollbars#3854
Conversation
commit: |
Bundle size report
Check out the code infra dashboard for more information about this PR. |
✅ Deploy Preview for base-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
| overflowY: scrollContainer.style.overflowY, | ||
| }; | ||
|
|
||
| html.style.scrollbarGutter = 'stable'; |
There was a problem hiding this comment.
scrollbar-gutter works as expected on the html element.
check blog css-overflow-3-spec
| export default function ScrollLock() { | ||
| const [enabled, setEnabled] = React.useState(false); | ||
| const [bodyScrollY, setBodyScrollY] = React.useState(false); | ||
| const [htmlScrollY, setHtmlScrollY] = React.useState(false); |
There was a problem hiding this comment.
Add htmlScrollY to ensure scroll blocking works correctly when overflow-y: scroll is set on .
This reverts commit 3806559.
Greptile OverviewGreptile SummaryImproved performance of scroll locking with classic scrollbars by minimizing full document style recalculations. The optimization detects the appropriate scroll container (body vs html) and applies changes there instead of always modifying html directly, reducing recalculations from 3 to 1 (Chromium 143) or 1 to 0 (Chromium 144). Key changes:
The implementation correctly handles state restoration for both html and body elements. Confidence Score: 5/5
Important Files Changed
|
| overflowY: scrollContainer.style.overflowY, | ||
| }; | ||
|
|
||
| html.style.scrollbarGutter = 'stable'; |
There was a problem hiding this comment.
scrollbarGutter set on html but saved/restored on scrollContainer. When scrollContainer is body, this leaves html.style.scrollbarGutter = 'stable' permanently set.
| html.style.scrollbarGutter = 'stable'; | |
| scrollContainer.style.scrollbarGutter = 'stable'; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/utils/src/useScrollLock.ts
Line: 42:42
Comment:
`scrollbarGutter` set on `html` but saved/restored on `scrollContainer`. When `scrollContainer` is `body`, this leaves `html.style.scrollbarGutter = 'stable'` permanently set.
```suggestion
scrollContainer.style.scrollbarGutter = 'stable';
```
How can I resolve this? If you propose a fix, please make it concise.|
In the demo when |
|
I missed that case — thanks for pointing it out. 😔
This difference comes from how the demo is configured:
This happens in the demo(master) as well if you manually disable
The layout shift issue occurs when I fixed this issue in this commit. So in the current demo, when |
atomiks
left a comment
There was a problem hiding this comment.
Nice, wasn't able to find any new issues with the latest implementation
Current
When using classic (inset) scrollbars with scroll locking, full document recalc can occur.
[Chromium 143]
3 full document recalc

[Chromium 144]
1 full document recalc

Cause
Directly changing
<html>styles causes a full document style recalculation.Solution
When checking scrollbar gutter stable, use body by default, except in cases where overflow-y: scroll is set on
<html>.Test
Improve
[Chromium 143]
1 full document recalc (Because we shoud set scrollbar-gutter in

html)[Chromium 144]
0 full document recalc

Limitation
Improving this behavior is not feasible for users who set overflow-y: scroll on
<html>.