Debounce vs. Throttle
Debounce runs after rapid events go quiet; throttle keeps running during them, but no more than once per chosen interval.
See it
What it is
Debounce waits for a quiet gap, then runs once with the latest call. Throttle allows calls at a limited pace while activity continues. A 300 ms debounce fits search suggestions after typing stops; a throttle fits progress that should keep updating during scroll or pointer movement.
Choose by the experience, not the event name. If intermediate updates have no value, debounce. If users need periodic feedback during a long burst, throttle. Lodash exposes leading and trailing options for both, plus maxWait for a debounce that must eventually fire.
Gotcha: a trailing debounce can be postponed forever by constant input, and a throttle with trailing disabled can lose the final value. Cancel pending work when a component unmounts, and do not recreate the wrapped function on every render or its timer keeps starting over.
Ask AI for it
Use Lodash _.debounce for the search input and _.throttle for the scroll progress indicator. Debounce search by 300 ms with trailing: true and maxWait: 1000 so continuous typing cannot postpone it forever. Throttle scroll updates to 100 ms with leading and trailing both true. Keep each wrapped function stable across React renders, pass the latest values without stale closures, and call .cancel() for both during effect cleanup. Add a test with fake timers proving the debounce waits for quiet while the throttle reports during the burst.