Rimanda il lavoro fino alla fine dello scorrimento

Funzionalità web: scrollend

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:

  1. Configura un contenitore scorrevole: crea un contenitore con overflow: auto o overflow: scroll.
  2. 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.
  3. Ascolta gli eventi scrollend: registra un callback scrollend sul contenitore di scorrimento o sul documento stesso.
  4. 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 scrollend anziché gli eventi scroll con 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 scrollSnapChange o scrollSnapChanging se 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);
  });
}