React-native-tab-view: Position listener sends too many events

Created on 4 Mar 2019  路  3Comments  路  Source: satya164/react-native-tab-view

Current behaviour

I've tailored the tab view to be able to have a tabbar that scrolls along as the user swipes through the pages. I'm using the position event listener to receive current position and calculate how far the scrollview (tabbar) should scroll.

It works great, however the listener sends so many events that the UI starts to lag and hangs for a second or so.

Expected behaviour

Is there any chance you can throttle the amount of events sent by the listener?

Code sample

public componentDidMount() {
    this.props.addListener('position', this.adjustScroll, 20);
  }

  public adjustScroll = (value: number) => {
    cancelAnimationFrame(this.scrollResetCallback);

    if (this.scrollView) {
      this.scrollView.scrollTo({
        animated: false,
        x: this.calculateScrollValue(value),
      });
    }
  };

 public calculateScrollValue = (position: number) =>
    Math.max(
      interpolate(position, {
        inputRange: [0, this.props.navigationState.routes.length - 1],
        outputRange: [
          0,
          this.getTabMeasurements(this.tabMeasurements.length - 1).centerOffset ||
            this.props.layout.width,
        ],
      }),
      0,
    );

Screenshots (if applicable)

/

What have you tried

I've tried throttling the incoming events, but it seems the bridge still slows down because of the event stream.

Your Environment

| software | version
| ---------------------------- | -------
| ios or android | iOS
| react-native | 0.59
| react-native-tab-view | 2.0.0-alpha.8
| react-native-gesture-handler | latest
| react-native-reanimated | latest
| node | 10 LTS
| npm or yarn | yarn

Most helpful comment

sth like:

const throttler = new Animated.Value(0)
const throttlingFactor = 16
...    
    cond(
      this._isListening,
      onChange(
        this._position,
        [
          cond(eq(throttler, 0), call([this._position], this._handlePositionChange)),
          set(throttler, modulo(add(throttler, 1), throttlingFactor))  
        ]
      )
    ),

All 3 comments

cc @osdnk do you know a way to throttle this listener for an animated value?

sth like:

const throttler = new Animated.Value(0)
const throttlingFactor = 16
...    
    cond(
      this._isListening,
      onChange(
        this._position,
        [
          cond(eq(throttler, 0), call([this._position], this._handlePositionChange)),
          set(throttler, modulo(add(throttler, 1), throttlingFactor))  
        ]
      )
    ),

Very good work, thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nastarfan picture nastarfan  路  3Comments

f6m6 picture f6m6  路  3Comments

Aravindhan12 picture Aravindhan12  路  4Comments

jouderianjr picture jouderianjr  路  3Comments

moerabaya picture moerabaya  路  4Comments