Skip to content

Commit bf52e2e

Browse files
committed
use requestAnimationFrame to avoid potential reflows in scroll event handlers
1 parent d91445f commit bf52e2e

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

polaris-react/src/components/Scrollable/Scrollable.tsx

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export function Scrollable({
6060

6161
useComponentDidMount(() => {
6262
if (hint) {
63-
performScrollHint(scrollArea.current);
63+
requestAnimationFrame(() => performScrollHint(scrollArea.current));
6464
}
6565
});
6666

@@ -72,18 +72,20 @@ export function Scrollable({
7272
}
7373

7474
const handleScroll = () => {
75-
const {scrollTop, clientHeight, scrollHeight} = currentScrollArea;
76-
const isBelowTopOfScroll = Boolean(scrollTop > 0);
77-
const isAtBottomOfScroll = Boolean(
78-
scrollTop + clientHeight >= scrollHeight - LOW_RES_BUFFER,
79-
);
80-
81-
setTopShadow(isBelowTopOfScroll);
82-
setBottomShadow(!isAtBottomOfScroll);
83-
84-
if (isAtBottomOfScroll && onScrolledToBottom) {
85-
onScrolledToBottom();
86-
}
75+
requestAnimationFrame(() => {
76+
const {scrollTop, clientHeight, scrollHeight} = currentScrollArea;
77+
const isBelowTopOfScroll = Boolean(scrollTop > 0);
78+
const isAtBottomOfScroll = Boolean(
79+
scrollTop + clientHeight >= scrollHeight - LOW_RES_BUFFER,
80+
);
81+
82+
setTopShadow(isBelowTopOfScroll);
83+
setBottomShadow(!isAtBottomOfScroll);
84+
85+
if (isAtBottomOfScroll && onScrolledToBottom) {
86+
onScrolledToBottom();
87+
}
88+
});
8789
};
8890

8991
const handleResize = debounce(handleScroll, 50, {trailing: true});
@@ -145,10 +147,12 @@ function performScrollHint(elem?: HTMLDivElement | null) {
145147
Math.min(MAX_SCROLL_HINT_DISTANCE, scrollableDistance) - LOW_RES_BUFFER;
146148

147149
const goBackToTop = () => {
148-
if (elem.scrollTop >= distanceToPeek) {
149-
elem.removeEventListener('scroll', goBackToTop);
150-
elem.scrollTo({top: 0, behavior: 'smooth'});
151-
}
150+
requestAnimationFrame(() => {
151+
if (elem.scrollTop >= distanceToPeek) {
152+
elem.removeEventListener('scroll', goBackToTop);
153+
elem.scrollTo({top: 0, behavior: 'smooth'});
154+
}
155+
});
152156
};
153157

154158
elem.addEventListener('scroll', goBackToTop);

0 commit comments

Comments
 (0)