bvaughn / react-window

React components for efficiently rendering large lists and tabular data
https://react-window.now.sh/
MIT License
15.72k stars 782 forks source link

requestTimeout based on requestAnimationFrame #628

Closed ronag closed 2 years ago

ronag commented 2 years ago

We are noticing some performance issues with requestAnimationFrame and notice that react-window does a lot of calls with that.

The root for this is:

    _resetIsScrollingDebounced = () => {
      if (this._resetIsScrollingTimeoutId !== null) {
        cancelTimeout(this._resetIsScrollingTimeoutId);
      }

      this._resetIsScrollingTimeoutId = requestTimeout(
        this._resetIsScrolling,
        IS_SCROLLING_DEBOUNCE_INTERVAL
      );
    };

Which use a rather peculiar requestTimeout which is based on polling requestAnimationFrame:

export function requestTimeout(callback: Function, delay: number): TimeoutID {
  const start = now();

  function tick() {
    if (now() - start >= delay) {
      callback.call(null);
    } else {
      timeoutID.id = requestAnimationFrame(tick);
    }
  }

  const timeoutID: TimeoutID = {
    id: requestAnimationFrame(tick),
  };

  return timeoutID;
}

I'm curious why this is used instead of simply using setTimeout? IS_SCROLLING_DEBOUNCE_INTERVAL is after all 150 ms and thus any reduced inaccuracy from setTimeout should not be relevant?

Is there something here I'm missing? Like is the scheduling priority important?

holmberd commented 2 years ago

@ronag Please see https://github.com/bvaughn/react-window/issues/106