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') {
const scrollContainer = this.scrollContainer;
const scrollContainerRect = scrollContainer.getBoundingClientRect();
const nextSlideRect = slide.getBoundingClientRect();
const nextLeft = nextSlideRect.left - scrollContainerRect.left;
const nextTop = nextSlideRect.top - scrollContainerRect.top;
if (nextLeft || nextTop) {
this.pendingSlideChange = true;
scrollContainer.scrollTo({
left: nextLeft + scrollContainer.scrollLeft,
top: nextTop + scrollContainer.scrollTop,
behavior
});
}
// Since the geometry doesn't happen until rAF, we don't know if we'll be scrolling or not...
// It's best to assume that we will and cleanup in the else case below if we didn't need to
this.pendingSlideChange = true;
window.requestAnimationFrame(() => {
const scrollContainer = this.scrollContainer;
const scrollContainerRect = scrollContainer.getBoundingClientRect();
const nextSlideRect = slide.getBoundingClientRect();
const nextLeft = nextSlideRect.left - scrollContainerRect.left;
const nextTop = nextSlideRect.top - scrollContainerRect.top;
if (nextLeft || nextTop) {
// 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() {