Fix rendering performance bottleneck in carousel (#2281)

* Fix rendering performance bottleneck in carousel

* Remove check before using RAF

* Optimistically mark the slide change as pending until the rAF callback runs
rothy-s-carousel-null-scrollContainer
Patrick McDougle 2024-12-04 11:49:19 -06:00 zatwierdzone przez GitHub
rodzic ac6414121a
commit 97fcab8f2a
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
1 zmienionych plików z 24 dodań i 15 usunięć

Wyświetl plik

@ -506,21 +506,30 @@ export default class SlCarousel extends ShoelaceElement {
} }
private scrollToSlide(slide: HTMLElement, behavior: ScrollBehavior = 'smooth') { private scrollToSlide(slide: HTMLElement, behavior: ScrollBehavior = 'smooth') {
const scrollContainer = this.scrollContainer; // Since the geometry doesn't happen until rAF, we don't know if we'll be scrolling or not...
const scrollContainerRect = scrollContainer.getBoundingClientRect(); // It's best to assume that we will and cleanup in the else case below if we didn't need to
const nextSlideRect = slide.getBoundingClientRect(); this.pendingSlideChange = true;
window.requestAnimationFrame(() => {
const nextLeft = nextSlideRect.left - scrollContainerRect.left; const scrollContainer = this.scrollContainer;
const nextTop = nextSlideRect.top - scrollContainerRect.top; const scrollContainerRect = scrollContainer.getBoundingClientRect();
const nextSlideRect = slide.getBoundingClientRect();
if (nextLeft || nextTop) {
this.pendingSlideChange = true; const nextLeft = nextSlideRect.left - scrollContainerRect.left;
scrollContainer.scrollTo({ const nextTop = nextSlideRect.top - scrollContainerRect.top;
left: nextLeft + scrollContainer.scrollLeft,
top: nextTop + scrollContainer.scrollTop, if (nextLeft || nextTop) {
behavior // This is here just in case someone set it back to false
}); // between rAF being requested and the callback actually running
} this.pendingSlideChange = true;
scrollContainer.scrollTo({
left: nextLeft + scrollContainer.scrollLeft,
top: nextTop + scrollContainer.scrollTop,
behavior
});
} else {
this.pendingSlideChange = false;
}
});
} }
render() { render() {