Lo scorrimento sul web deve essere fluido e reattivo. L'esecuzione di attività pesanti, come i ricalcoli del layout, il monitoraggio dei beacon dei dati di analisi o gli aggiornamenti dinamici del DOM, durante lo scorrimento può saturare il thread principale, con conseguente perdita di frame e thrashing del layout.
In passato, gli sviluppatori si affidavano al debouncing dell'evento scroll utilizzando setTimeout() per indovinare quando uno scorrimento era terminato. Tuttavia, queste funzioni con debounce sono notoriamente inaffidabili. Potrebbero attivarsi mentre l'utente sta ancora scorrendo.
L'evento scrollend offre una soluzione altamente affidabile e basata sul rendimento. Il browser attiva un evento scrollend esattamente quando lo scorrimento si è interrotto, tutte le transizioni sono terminate e un gesto di tocco è stato rilasciato.
Modalità di implementazione
Per implementare un pattern di rinvio del lavoro:
- Configura un contenitore scorrevole: crea un contenitore con
overflow: autoooverflow: scroll. - Ascolta gli eventi
scroll: utilizza questo listener solo per metriche dinamiche di base o per lo stile del layout informativo. Non eseguire lavori pesanti qui. - Ascolta gli eventi
scrollend: registra un callbackscrollendsul contenitore di scorrimento o sul documento stesso. - Esegui operazioni costose nel callback: è qui che puoi recuperare in sicurezza i contenuti dinamici o attivare layout DOM completi.
Codice di esempio
.scroll-container {
height: 300px;
overflow-y: auto;
}
const scroller = document.querySelector('.scroll-container');
// 1. Informative feedback during scroll
scroller.addEventListener('scroll', () => {
// Avoid dynamic heavier data updates here
console.log('Scrolling dynamically... updates deferred');
});
// 2. Safe callback when scrolling rests
scroller.addEventListener('scrollend', () => {
// Run layout recalculations or analytical beacons updates here
const currentVisibleSection = findMostVisibleSection(scroller);
fetchAdditionalData(currentVisibleSection);
});
Implementazione strategica e best practice
- SÌ: utilizza
scrollendanziché gli eventiscrollcon debounce quando attivi i beacon dei dati di layout o recuperi dinamicamente un nuovo layout dei contenuti. - SÌ: valuta la possibilità di abbinare questa funzionalità alle interazioni di aggancio
scrollSnapChangeoscrollSnapChangingse stai creando caroselli o slide di gallerie di testimonianze. - NON raggruppare gli aggiornamenti dinamici dipendenti dal layout all'interno dei callback di scorrimento visivo dinamico.
- SÌ: tieni presente che lo zoom e lo scorrimento della visual viewport attivano correttamente l'evento
scrollend.
Strategia di riserva
Per i browser non supportati, utilizza un evento scroll con debounce con setTimeout per inviare un evento scrollend personalizzato.
function initializeDemo() {
const scroller = document.querySelector('#scroller');
scroller.addEventListener('scrollend', () => {
// Safe execution
});
}
if ('onscrollend' in window) {
initializeDemo();
} else {
initializeDemo();
const scroller = document.querySelector('#scroller');
scroller.addEventListener('scroll', () => {
clearTimeout(window.scrollendtimer);
window.scrollendtimer = setTimeout(() => {
scroller.dispatchEvent(new CustomEvent('scrollend'));
}, 100);
});
}