Откладывать работу до окончания прокрутки

Веб-функции: scrollend

Прокрутка на веб-страницах должна быть плавной и быстрой. Выполнение тяжелых задач, таких как перерасчет макета, отслеживание маяков аналитических данных или динамические обновления DOM, во время прокрутки может насытить основной поток, что приведет к потере кадров и сбою макета.

Раньше разработчики использовали устранение дребезга контактов события scroll с помощью setTimeout(), чтобы определить, когда прокрутка завершена. Однако эти функции дебаунсинга известны своей ненадежностью. Они могут сработать, пока пользователь ещё прокручивает страницу.

Событие scrollend – это надежное решение, ориентированное на эффективность. Браузер запускает событие scrollend, когда прокрутка останавливается, все переходы завершаются и пользователь отпускает экран.

Как реализовать

Чтобы реализовать шаблон отложенной работы:

  1. Настройте прокручиваемый контейнер. Создайте контейнер с помощью overflow: auto или overflow: scroll.
  2. Прослушивание событий scroll. Используйте этот прослушиватель только для базовых динамических показателей или информативного оформления макета. Не выполняйте здесь тяжелую работу.
  3. Прослушивание событий scrollend. Зарегистрируйте обратный вызов scrollend в контейнере прокрутки или в самом документе.
  4. Выполняйте ресурсоемкие задачи в обратном вызове. Это безопасный способ получать динамический контент или запускать сложные макеты DOM.

Пример кода

.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);
});

Стратегическое внедрение и рекомендации

  • РЕКОМЕНДУЕТСЯ использовать scrollend вместо событий scroll с дебаунсингом при отправке веб-маяков с данными о макете или динамическом получении нового макета контента.
  • РЕКОМЕНДУЕТСЯ использовать этот атрибут вместе с взаимодействиями scrollSnapChange или scrollSnapChanging, если вы создаете карусели или слайды с отзывами.
  • НЕ объединяйте динамические обновления, зависящие от макета, в обратных вызовах динамической визуальной прокрутки.
  • РЕКОМЕНДУЕТСЯ учитывать, что масштабирование и прокрутка области просмотра корректно активируют событие scrollend.

Резервная стратегия

Для неподдерживаемых браузеров используйте событие scroll с setTimeout, чтобы отправлять специальное событие scrollend.

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);
  });
}