throttleTime

throttleTime postpones the values coming from a source for a specified duration. Much like debounceTime, it helps manage how frequently values reach an observer. However, unlike debounceTime, throttleTime ensures that emissions happen at consistent, regular intervals, never exceeding the configured rate.

An optional configuration object can alter the operator’s behavior: {leading: boolean, trailing: boolean}. By default, it is set to {leading: true, trailing: false}.

With the default settings {leading: true, trailing: false}, the operator functions as follows:

  1. upon receiving a new value, it initiates a timer for the specified duration
  2. it immediately passes the value to the observer
  3. any values arriving before the timer completes are discarded

For the configuration {leading: true, trailing: true}, the operator works like this:

  1. a timer is started when a new value arrives
  2. that value is emitted right away
  3. if other values come in during the timer, the most recent one is stored and replaces any previously saved value
  4. when the timer expires, the stored value is emitted to the observer

With the configuration {leading: false, trailing: true}, the behavior changes to:

  1. a timer begins when a new value arrives
  2. the value is held back, not sent out
  3. subsequent values during the timer overwrite the kept value
  4. on timer completion, the final kept value is emitted

Internally, the operator relies on setInterval via the AsyncScheduler for its scheduling.

Practical Use

This operator is particularly useful for events that can fire dozens or even hundreds of times within a single second. Common examples include native DOM events like scrolling, window resizing, mouse movement, and keyboard input.

Consider a scroll listener on a page. Scrolling down to, say, 5000 pixels could easily generate over a hundred events. If your event handler involves complex operations like heavy calculations or extensive DOM updates, performance can suffer, leading to visible jank. Limiting how often that handler runs, without compromising the user experience, can bring substantial performance gains.

It’s also wise to throttle any interaction that touches off intensive computations or repeated API calls.

Below is an example of applying throttleTime to an input field:

const inputElement = document.createElement('input');
document.body.appendChild(inputElement);

fromEvent(inputElement, 'input')
   .pipe(
       throttleTime(500),
       map((event: any) => event.target.value)
   ).subscribe(val => console.log(val));

Live Demo

Leading – true, Trailing – false

Leading – true, Trailing – true

Leading – false, Trailing – true

Further Reading