The addEventListener
method now accepts an optional, third AddEventListenerOptions
argument 1. I propose adding options for event throttling and debouncing.
Example use case: Network Information API 3
navigator.connection.addEventListener('change', () => {
// inspect navigator.connection
}, { debounce: true });
The change
event fires multiple times in rapid succession, e.g., when the user’s connection switches from Wi-Fi to cellular 2, so it would be useful if a web app could specify that the event handler should be called only once after the final event (a.k.a. event debouncing).
If you have other examples of when event throttling or debouncing is needed, please comment below.
Update: Based on the discussion (as of November 20), I think it makes sense to treat debouncing and throttling as separate proposals, since their use cases are different.
Use cases for event debouncing:
- Debounce the Network Information API
change
event, since only the last event is relevant when multiple events fire in rapid succession. - Debounce keyboard events when the user is typing into a form field, to be able to perform an action (e.g. load search results) when the user stops typing.
- Debounce the global
resize
event when the user resizes the browser window1. This event fires in rapid succession during a single user operation (demo), so a web app may want to receive a single event after the user has stopped resizing the browser window, in order to perform “UI changes that aren’t easily achievable with media queries.”
Use cases for event throttling:
- Throttle mouse events to a lower frequency (e.g., 20 Hz) when displaying mouse coordinates in the app’s UI to conserve processing power, since users can’t perceive UI updates at a higher frequency anyway.
Footnotes:
- There is a new Resize Observer API, which can notify the web app when an element’s size changes via resize entries. However, the same problem of multiple entries firing in rapid succession exists, so this new API does not remove the need for debouncing
resize
events in the use case described above.