Debounce и throttle

При разработке интерфейсов на SvelteKit часто возникает необходимость оптимизировать обработку событий, которые могут срабатывать слишком часто, таких как scroll, resize, input или keydown. Для этого применяются методы debounce и throttle, позволяющие контролировать частоту вызова функций, улучшать производительность и снижать нагрузку на браузер.


Debounce

Debounce — это техника, при которой функция выполняется только после того, как прошло определённое время с момента последнего вызова. Если событие повторяется, таймер сбрасывается. Это особенно полезно для поиска по мере ввода текста, автосохранений и фильтров.

Пример реализации debounce в SvelteKit:

// debounce.js
export function debounce(fn, delay = 300) {
    let timeout;
    return (...args) => {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn(...args);
        }, delay);
    };
}

Использование внутри компонента SvelteKit:

<script>
    import { debounce } fr om './debounce.js';
    import { writable } fr om 'svelte/store';

    const searchQuery = writable('');

    function handleInput(event) {
        searchQuery.set(event.target.value);
        console.log('Поиск:', event.target.value);
    }

    const debouncedInput = debounce(handleInput, 500);
</script>

<input type="text" placeholder="Поиск..." on:input={debouncedInput} />

Ключевые моменты:

  • debounce откладывает выполнение функции до тех пор, пока события не прекратятся на время delay.
  • Подходит для ввода текста, запросов к API и других событий, которые происходят часто, но не требуют мгновенной реакции.

Throttle

Throttle ограничивает выполнение функции так, чтобы она срабатывала не чаще одного раза за заданный интервал. Это полезно для событий, которые происходят постоянно, но должны обрабатываться с фиксированным интервалом, например scroll или mousemove.

Пример реализации throttle в SvelteKit:

// throttle.js
export function throttle(fn, lim it = 300) {
    let lastCall = 0;
    return (...args) => {
        const now = Date.now();
        if (now - lastCall >= lim it) {
            lastCall = now;
            fn(...args);
        }
    };
}

Использование в компоненте:

<script>
    import { throttle } from './throttle.js';

    function handleScroll(event) {
        console.log('Прокрутка Y:', window.scrollY);
    }

    const throttledScroll = throttle(handleScroll, 200);

    // Привязка события к window
    window.addEventListener('scroll', throttledScroll);
</script>

Ключевые моменты:

  • throttle обеспечивает регулярное выполнение функции с фиксированным интервалом.
  • Подходит для контроля прокрутки, движения мыши, ресайза окна и других «постоянных» событий.

Отличия debounce и throttle

Параметр Debounce Throttle
Частота вызова Только после остановки событий Не чаще, чем заданный интервал
Применение Ввод текста, автосохранение Scroll, mousemove, resize
Поведение Сбрасывает таймер при каждом событии Игнорирует вызовы до окончания интервала

Интеграция с SvelteKit Stores

Debounce и throttle удобно использовать совместно с SvelteKit stores для реактивных данных. Например, при автосохранении формы:

<script>
    import { writable } from 'svelte/store';
    import { debounce } from './debounce.js';

    const formData = writable({ name: '', email: '' });

    function saveForm(data) {
        console.log('Сохраняем форму:', data);
        // Запрос к API или локальное сохранение
    }

    const debouncedSave = debounce((data) => saveForm(data), 1000);
</script>

<input type="text" placeholder="Имя" on:input={(e) => { formData.update(f => ({ ...f, name: e.target.value })); debouncedSave($formData); }} />
<input type="email" placeholder="Email" on:input={(e) => { formData.update(f => ({ ...f, email: e.target.value })); debouncedSave($formData); }} />

Такое решение уменьшает количество вызовов функции сохранения, делая интерфейс более отзывчивым и экономя ресурсы.


Настройка параметров

  • delay в debounce определяет, сколько миллисекунд ждать после последнего события.
  • limit в throttle задаёт минимальный интервал между вызовами.
  • Подбор этих значений зависит от частоты событий и требований к отзывчивости интерфейса.

Использование с SvelteKit Actions и событиями компонента

Debounce и throttle можно применять не только к DOM-событиям, но и к реактивным обработчикам SvelteKit. Например, при отслеживании изменений в reactive statements:

<script>
    import { debounce } from './debounce.js';
    let value = '';

    $: debouncedValue = debounce(() => {
        console.log('Debounced reactive:', value);
    }, 500)();
</script>

<input type="text" bind:value />

Такой подход позволяет контролировать частоту реактивных вычислений и минимизировать ненужные обновления интерфейса.


Debounce и throttle являются ключевыми инструментами для создания производительных интерфейсов в SvelteKit. Их использование позволяет уменьшить нагрузку на браузер, управлять частотой вызовов функций и создавать более отзывчивые приложения.