Skip to content

Commit cb7ab76

Browse files
committed
fix performance issue when using css-custom-properties in scroll timeline animation (#705)
1 parent 1126a47 commit cb7ab76

1 file changed

Lines changed: 40 additions & 6 deletions

File tree

packages/overlayscrollbars/src/setups/scrollbarsSetup/scrollbarsSetup.elements.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,27 +116,55 @@ export const createScrollbarsSetupElements = (
116116

117117
const initScrollTimeline = (axis: keyof XY<unknown>) => {
118118
if (scrollT) {
119+
let currAnimation: Animation | null = null;
120+
let currAnimationTransform: string[] = [];
119121
const timeline = new scrollT({
120122
source: _scrollOffsetElement,
121123
axis,
122124
});
125+
const cancelAnimation = () => {
126+
currAnimation && currAnimation.cancel();
127+
currAnimation = null;
128+
};
129+
const _setScrollPercentAnimation = (structure: ScrollbarStructure) => {
130+
const { _scrollCoordinates } = structureSetupState;
131+
const defaultDirectionScroll =
132+
isDefaultDirectionScrollCoordinates(_scrollCoordinates)[axis];
133+
const isHorizontal = axis === 'x';
134+
const transformArray = [
135+
getTrasformTranslateValue(0, isHorizontal),
136+
getTrasformTranslateValue(`calc(100cq${isHorizontal ? 'w' : 'h'} + -100%)`, isHorizontal),
137+
];
138+
const transform = defaultDirectionScroll ? transformArray : transformArray.reverse();
123139

124-
const _addScrollPercentAnimation = (structure: ScrollbarStructure) => {
125-
const scrollPercentAnimation = structure._scrollbar.animate(
140+
if (
141+
currAnimationTransform[0] === transform[0] &&
142+
currAnimationTransform[1] === transform[1]
143+
) {
144+
return cancelAnimation;
145+
}
146+
147+
cancelAnimation();
148+
currAnimationTransform = transform;
149+
currAnimation = structure._handle.animate(
126150
{
127151
// dummy keyframe which fixes bug where the scrollbar handle is reverted to origin position when it should be at its max position
128152
clear: ['left'],
129-
[cssCustomPropScrollPercent]: [0, 1],
153+
// transform is a temporary fix for: https://github.com/KingSora/OverlayScrollbars/issues/705
154+
// can be reverted to just animate "cssCustomPropScrollPercent" when browsers implement an optimization possibility
155+
transform,
156+
// [cssCustomPropScrollPercent]: [0, 1],
130157
},
131158
{
132159
timeline,
133160
}
134161
);
135-
return () => scrollPercentAnimation.cancel();
162+
163+
return cancelAnimation;
136164
};
137165

138166
return {
139-
_addScrollPercentAnimation,
167+
_setScrollPercentAnimation,
140168
};
141169
}
142170
};
@@ -232,6 +260,12 @@ export const createScrollbarsSetupElements = (
232260

233261
scrollbarStyle(horizontalScrollbars, createScrollbarStyleFn(defaultDirectionScroll.x));
234262
scrollbarStyle(verticalScrollbars, createScrollbarStyleFn(defaultDirectionScroll.y));
263+
264+
// temporary fix for: https://github.com/KingSora/OverlayScrollbars/issues/705
265+
if (scrollT) {
266+
horizontalScrollbars.forEach(scrollTimeline.x!._setScrollPercentAnimation);
267+
verticalScrollbars.forEach(scrollTimeline.y!._setScrollPercentAnimation);
268+
}
235269
};
236270
const refreshScrollbarsScrollbarOffset = () => {
237271
if (_viewportIsTarget && !_isBody) {
@@ -288,7 +322,7 @@ export const createScrollbarsSetupElements = (
288322
appendChildren(scrollbar, track),
289323
appendChildren(track, handle),
290324
bind(removeElements, scrollbar),
291-
timeline && timeline._addScrollPercentAnimation(result),
325+
timeline && timeline._setScrollPercentAnimation(result),
292326
scrollbarsSetupEvents(result, scrollbarsAddRemoveClass, isHorizontal),
293327
]);
294328

0 commit comments

Comments
 (0)