React-native-tab-view: Not performant on large routes

Created on 19 May 2019  Â·  3Comments  Â·  Source: satya164/react-native-tab-view


Current behaviour

Trying to use it to make dynamic tabs based on data provided in a quite big array (120 entries of data), but having performance issues when loading the tab view and switching between tabs.

Expected behaviour

I've read and followed Optimization Tips and expected it to be performant but even loading the tabs takes ages.

Code sample

Here's a code to reproduce the issue

class TemplateScreen extends PureComponent {
  // sample 'template' screen to display the data
  render() {
    const {
      route: { key },
    } = this.props;

    return (
      <View style={styles.container}>
        <Text>I am {key} screen</Text>
      </View>
    );
  }
}

export default class ProduceBug extends Component {
  constructor(props) {
    super(props);
    const data = Array.from({ length: 120 }); // dummy data, routes are populated from it
    const routes = [];

    data.forEach((item, index) => {
      routes.push({
        // create route object and push it to routes
        key: (index + 1).toString(),
        title: (index + 1).toString(),
      });
    });

    this.state = {
      index: 0,
      routes,
    };
  }

  renderScene = ({ route }) => {
    const { index, routes } = this.state;

    if (Math.abs(index - routes.indexOf(route)) > 2) {
      // only renders left and right scene
      return <View />;
    }
    return <TemplateScreen route={route} />;
  };

  renderTabBar = (props) => (
    <TabBar
      {...props}
      scrollEnabled
      indicatorStyle={styles.indicator}
      style={styles.tabbar}
      tabStyle={styles.tab}
      labelStyle={styles.label}
    />
  );

  render() {
    const initialLayout = {
      height: 0,
      width: Dimensions.get('window').width,
    };

    return (
      <TabView
        navigationState={this.state}
        onIndexChange={(index) => this.setState({ index })}
        initialLayout={initialLayout}
        renderScene={this.renderScene}
        renderTabBar={this.renderTabBar}
        lazy
      />
    );
  }
}

What have you tried

It works well with small number of data, like 5, but once it gets bigger it becomes very laggy. I've tried to improve the performance by following provided tips, but can't really achieve tolerable performance

Your Environment

| software | version
| ---------------------------- | -------
| ios or android | android
| react-native | 0.59.5
| react-native-tab-view | 2.2.0
| react-native-gesture-handler | 1.2.0
| react-native-reanimated | 1.0.1

Most helpful comment

Please reopen. I have the same issue after upgrade to the latest version. The new default TabBarItem take a very long time to render.

Here's some performance tracking of the same code, rendering 50 routes

Version 2.5.0 (~2600ms)

perf

Version 1.4.1 (~250ms)

perf2

Reproducible sample code

https://snack.expo.io/@dhl1402/react-native-tabview-reproduce-repo

All 3 comments

Please upgrade to the latest version which should have improved performance #720

even loading the tabs takes ages.

In the example, there are 120 tabs being rendered, and even if you're not rendering the screens itself, the tabbar still has to render all of the route labels. If you don't render the tab bar, there's no issue with performance from what I tested.

You can re-implement the tabbar to fit your use case. The default tab bar is not made for such a huge amount of routes.

Please reopen. I have the same issue after upgrade to the latest version. The new default TabBarItem take a very long time to render.

Here's some performance tracking of the same code, rendering 50 routes

Version 2.5.0 (~2600ms)

perf

Version 1.4.1 (~250ms)

perf2

Reproducible sample code

https://snack.expo.io/@dhl1402/react-native-tabview-reproduce-repo

hey @dhl1402 did you find a solution to optimise tabbar time to mount ?

Was this page helpful?
0 / 5 - 0 ratings