В библиотеке Interact.js часто возникает
необходимость оптимизировать обработку событий, связанных с движением
элементов, масштабированием или перетаскиванием. Когда события
происходят очень часто (например, mousemove или
resize), прямое реагирование на каждое событие может
привести к значительной нагрузке на браузер и снижению
производительности. Именно здесь на помощь приходят техники
throttle и debounce.
Throttle ограничивает количество вызовов функции,
позволяя ей выполняться не чаще, чем раз в определённый интервал
времени. Это особенно полезно для событий, которые происходят с высокой
частотой, таких как перетаскивание (dragmove) или
масштабирование (resizemove).
interact('.draggable').draggable({
listeners: {
move: throttle(function (event) {
const target = event.target;
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
target.style.transform = `translate(${x}px, ${y}px)`;
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}, 100) // ограничение вызова функции до одного раза в 100 мс
}
});
Ключевой момент: Время задержки в миллисекундах
(100 в примере) определяет частоту
обновлений, что позволяет контролировать производительность и
отзывчивость интерфейса.
Debounce откладывает вызов функции до тех пор, пока события не перестанут происходить на протяжении заданного времени. Это идеально для ситуаций, когда необходимо реагировать только на завершение действия, а не на каждый промежуточный шаг.
function savePosition(event) {
console.log('Сохраняем позицию элемента', event.target.id);
}
interact('.draggable').draggable({
listeners: {
end: debounce(savePosition, 300) // вызов после окончания действия с задержкой 300 мс
}
});
Ключевой момент: debounce помогает
избежать лишних вычислений или сетевых запросов при высокочастотных
событиях.
throttle и
debounce| Характеристика | Throttle | Debounce |
|---|---|---|
| Когда вызывается | Периодически, с фиксированным интервалом | Только после того, как события прекратились |
| Подходит для | Частых обновлений UI, перетаскивания | Завершение действия, отправка данных, поиск |
| Поведение при частых событиях | Игнорирует промежуточные события | Сбрасывает таймер и откладывает вызов |
Interact.js предоставляет мощные события для
перетаскивания, масштабирования и жестов. С помощью
throttle и debounce можно:
dragmove) для плавности.dragend).resizemove).interact('.resizable').resizable({
edges: { left: true, right: true, bottom: true, top: true },
listeners: {
move: throttle(function (event) {
let { x, y } = event.target.dataset;
x = (parseFloat(x) || 0);
y = (parseFloat(y) || 0);
Object.assign(event.target.style, {
width: `${event.rect.width}px`,
height: `${event.rect.height}px`,
transform: `translate(${x}px, ${y}px)`
});
}, 50) // обновление не чаще чем раз в 50 мс
}
});
interact('.draggable').draggable({
listeners: {
end: debounce(function (event) {
fetch('/save-position', {
method: 'POST',
body: JSON.stringify({ id: event.target.id, x: event.target.dataset.x, y: event.target.dataset.y })
});
}, 200) // отправка данных через 200 мс после завершения перетаскивания
}
});
Interact.js не содержит собственных реализаций throttle
и debounce, поэтому обычно используют:
_.throttle, _.debounce_.throttle, _.debouncethrottlefunction throttle(fn, limit) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= limit) {
lastCall = now;
fn.apply(this, args);
}
};
}
debouncefunction debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
Эффективное использование throttle и debounce в Interact.js позволяет контролировать производительность интерфейса, снижать нагрузку на браузер и обеспечивать плавность взаимодействия с элементами, одновременно избегая лишних операций при завершении действий.