В работе с событиями DOM часто возникает необходимость контролировать
частоту вызова функций, особенно при интенсивных событиях, таких как
scroll, resize или mousemove.
Библиотека ally.js предоставляет удобные инструменты
для управления доступностью и взаимодействием, но для оптимизации
производительности и предотвращения перегрузки браузера важно
комбинировать её с подходами throttling и
debouncing.
Debouncing — это метод, при котором функция вызывается только после того, как событие перестало происходить в течение определённого времени. Он эффективен для предотвращения лишних вызовов при непрерывных событиях.
import { focusWithin } fr om 'ally.js';
function highlightFocusedElement() {
const element = focusWithin();
if (element) {
element.classList.add('highlight');
}
}
// Debounce функция с задержкой 300 мс
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
const debouncedHighlight = debounce(highlightFocusedElement, 300);
document.addEventListener('focusin', debouncedHighlight);
В этом примере функция highlightFocusedElement
вызывается только после того, как пользователь перестал
переключать фокус на элементы на 300 мс. Это снижает нагрузку
на DOM и предотвращает частые изменения классов.
Throttling ограничивает частоту вызова функции, позволяя выполнять её не чаще, чем один раз за заданный интервал времени. Этот подход полезен для событий, происходящих с высокой скоростью, где важно получать обновления с определённой периодичностью.
import { tabFocus } fr om 'ally.js';
function logTabFocus() {
const focusedElement = tabFocus();
if (focusedElement) {
console.log('Focused element:', focusedElement);
}
}
// Throttle функция с интервалом 200 мс
function throttle(func, lim it) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= lim it) {
lastCall = now;
func.apply(this, args);
}
};
}
const throttledLogFocus = throttle(logTabFocus, 200);
document.addEventListener('keydown', throttledLogFocus);
Здесь logTabFocus будет выполняться не чаще одного раза
каждые 200 мс, даже если пользователь быстро переключает фокус с помощью
клавиши Tab.
| Характеристика | Debounce | Throttle |
|---|---|---|
| Когда вызывается функция | После окончания серии событий | С периодичностью во время событий |
| Применение | Ввод текста, поиск, изменения размера окна | Скролл, движение мыши, анимации |
| Эффект | Минимизирует вызовы до одного | Контролирует частоту вызовов |
Debounce идеально подходит для функций, которые реагируют на события focus или ввод текста, например:
focusWithin.Throttle эффективен для функций, связанных с глобальными событиями интерфейса, например:
tabFocus.Можно объединить debounce и throttle в одну обёртку для управления событиями, где выбор метода зависит от характера события:
function createEventHandler(func, { mode = 'debounce', delay = 200 }) {
if (mode === 'debounce') {
return debounce(func, delay);
} else if (mode === 'throttle') {
return throttle(func, delay);
}
return func;
}
const handleFocusChange = createEventHandler(highlightFocusedElement, { mode: 'debounce', delay: 300 });
const handleScrollFocus = createEventHandler(logTabFocus, { mode: 'throttle', delay: 150 });
document.addEventListener('focusin', handleFocusChange);
document.addEventListener('scroll', handleScrollFocus);
Такой подход позволяет оптимизировать производительность и сохранять реактивность интерфейса, используя возможности ally.js для управления доступностью.