Learning Objectives
- Identify the high-frequency events and what they cost
- Throttle: run at most once per interval, while activity continues
- Debounce: run once, after activity stops
- Choose between them by asking what the handler is for
- Mark scroll and touch listeners
passive
Two small functions
Both tools are wrappers: give them your handler and a wait time, get back a rate-limited version to hand to addEventListener. These are the demo's actual implementations — a dozen lines, no library:
Throttle lets the handler through at most once per wait milliseconds — a steady drumbeat while events keep arriving. Debounce resets a timer on every event and fires only when the events stop for wait milliseconds — silence, then one call.
Watch the counters diverge
The demo wires the same events to normal, throttled, and debounced handlers side by side. Drag the scroll box and the normal counter races ahead while throttle ticks steadily and debounce waits for you to stop. Then try the two search inputs — the canonical case. Every keystroke in the plain input is an “API call”; the debounced one waits 500 ms of quiet and makes one:
The resize section watches the window, so its counters only move when the window actually resizes — open the demo standalone and drag an edge to see it.
The browser's half: passive listeners
Rate-limiting fixes how often your code runs. There is a second cost you cannot fix with less code: for scroll and touch events, the browser must wait for your handler before moving the page, because you might call preventDefault(). Declaring the listener passive is a promise you won't:
With that promise made, scrolling never blocks on your JavaScript. The two techniques compose: passive tells the browser it may proceed without you; throttle and debounce decide how often you bother showing up at all.
Next Steps
That completes the event model: binding, the event object, flow, delegation, forms, your own events, and the firehose. Everything from here on uses it. In The DOM series, events are how every demo is driven — and the tree is what they drive:
- The parse tree the browser builds from your markup
- Selecting, walking, modifying, creating, and destroying nodes
- Geometry, observers, and the libraries beyond the raw DOM