Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FlatList] onScroll's event is "stuttering" #14037

Closed
Exilz opened this issue May 18, 2017 · 11 comments
Closed

[FlatList] onScroll's event is "stuttering" #14037

Exilz opened this issue May 18, 2017 · 11 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@Exilz
Copy link

Exilz commented May 18, 2017

I'm trying to implement a ScrollView that animates the Y position of a slider.
My ScrollView is actually a FlatList, and I'm using onScroll to animate the position of my slider.

I tried to use a Animated.View and use position.setValue in the onScroll event.
I also tried to use ref.setNativeProps to see if that speeds things up a bit, but the result is exactly the same.

It made me understand that it's not the animation that is slow, but the onScroll event that is "stuttering".

Here's the result with a ListView (smooth as a baby's butt)

And here's what's happening with FlatList

It's even more striking when looking at the app at 60 fps.

Is there some kind of optimizations on FlatList that throttles the onScroll event ? Maybe there is or there should be a way to opt-out of some of those ?

@hjh5696
Copy link

hjh5696 commented May 24, 2017

I have a similar issue. I have a header(Animated.View) that has an absolute position above the FlatList. When I tried to animate the header by onScroll of FlatList, the animation stuttered. I also tried useNativeDriver: true, but the problem remained same.
If I use SectionList instead of FlatList, the animation is smooth enough. Is it a bug in FlatList?

@timrc
Copy link

timrc commented May 26, 2017

I am having the same issues here. I'm animating an absolute header at the top by FlatList onScroll event and it's just not there. ScrollView is smooth butter.

@Komeyl94
Copy link

I have the same problem as @hjh5696 @timrc

@whtlnv
Copy link

whtlnv commented May 29, 2017

I migrated a ListView that holds 60 rows (each with ~11 nested views, 4 images, 6 Texts and Touchable) and definitively experienced stuttering when scrolling down the FlatList, which didn't happen with aListView. No animation was used on either.

This was very noticeable when testing my worst case scenario iOS device (iPhone 5S). Android didn't seem to suffer, but the test device is much more recent (Motorola G4 Plus).

@tijp
Copy link

tijp commented Jun 2, 2017

To fix this you need to set FlatList's scrollEventThrottle prop to ~16 (amount of milliseconds how often it should update every second, you ideally want 60 fps so 1000ms/60fps = ~16ms).

However there is an issue where the value of scrollEventThrottle in the VirtualizedList (which FlatList is a wrapper of) is hardcoded to 50. This means that it will only update every 50ms (1000ms/50ms = 20fps). Luckily they have already fixed this, so that you can manually change it's value again. This will be shipped however in v0.45.
See #13267.

I tested it in v0.45-rc2 and when setting scrollEventThrottle to 16 it works smooth again 😄

@hramos hramos changed the title Flatlist onScroll's event is "stuttering" [FlatList] onScroll's event is "stuttering" Jun 2, 2017
@hramos
Copy link
Contributor

hramos commented Jun 2, 2017

Hey, thanks for reporting this issue!

It looks like your description is missing some necessary information. Can you please add all the details specified in the template? This is necessary for people to be able to understand and reproduce the issue being reported.

I am going to close this, but feel free to open a new issue with the additional information provided. Thanks!

@KakarN
Copy link

KakarN commented Sep 3, 2017

Hi! I think the issue has reappeared. However, in my case, both the Animated.ScrollView and Animated.FlatList has the same issue. I have opened an issue #15769 for this.

@mileung
Copy link

mileung commented Jan 3, 2018

Animated.FlatList (and "Animated.Flatlist" I think that is a typo) is an invalid component for me in RN V0.51

@MacKentoch
Copy link
Contributor

MacKentoch commented Feb 16, 2018

Issue with RN 0.51

Using onScroll to animate an Header is not smooth on Android ONLY (emulator and real device).

        scrollY = new Animated.Value(0);
        ///...
        
        // in render method:

     const headerHeight = this.scrollY.interpolate({
      inputRange: [0, HEADER_SCROLL_DISTANCE],
      outputRange: [HEADER_MAX_HEIGHT, HEADER_MIN_HEIGHT],
      extrapolate: 'clamp',
    });

    const titleTopPadding = this.scrollY.interpolate({
      inputRange: [0, HEADER_SCROLL_DISTANCE],
      outputRange: [HEADER_MAX_HEIGHT * 2 / 3, 0],
      extrapolate: 'clamp',
    });

    const titleTextSize = this.scrollY.interpolate({
      inputRange: [0, HEADER_SCROLL_DISTANCE],
      outputRange: [32, 18],
      extrapolate: 'clamp',
    });

    const listMarginTop = this.scrollY.interpolate({
      inputRange: [0, HEADER_SCROLL_DISTANCE],
      outputRange: [HEADER_MAX_HEIGHT, HEADER_MIN_HEIGHT],
      extrapolate: 'clamp',
    }); 

        // jsx:
        {/* header */}
        <Animated.View style={[styles.header, { height: headerHeight }]}>
          <View style={styles.bar}>
            <Animated.Text
              style={[
                styles.title,
                {
                  paddingTop: titleTopPadding,
                  fontSize: titleTextSize,
                },
              ]}
            >
              {I18n.t('EVENTS_LIST')}
            </Animated.Text>
          </View>
        </Animated.View>
        {/* list */}
        <Animated.View style={[styles.container, { marginTop: listMarginTop }]}>
         <FlatList
            data={events}
            scrollEventThrottle={16}
            onScroll={Animated.event([
              { nativeEvent: { contentOffset: { y: this.scrollY } } },
            ])}
            keyExtractor={this.eventsKeyExtractor}
            renderItem={this.renderEventsItem}
            ListHeaderComponent={this.renderHeader}
            indicatorStyle="default"
          />
        </Animated.View/

@MacKentoch
Copy link
Contributor

MacKentoch commented Feb 17, 2018

I fixed my issue by:

  • using SectionList instead of FlatList
  • removed top margin animated (drop of listMarginTop in my upper code) replaced by Section list header (to set a fixed margin = max animaetd height = HEADER_MAX_HEIGHT)
  • don't use { useNativeDriver: true } since it was throwing error and seems like not reliable on android (if I'm wrong sorry but I did not take all the time to search and test it)
    // interpolations 
    const headerHeight = this.scrollY.interpolate({
      inputRange: [0, HEADER_SCROLL_DISTANCE],
      outputRange: [HEADER_MAX_HEIGHT, HEADER_MIN_HEIGHT],
      extrapolate: 'clamp',
    });

    const titleTopPadding = this.scrollY.interpolate({
      inputRange: [0, HEADER_SCROLL_DISTANCE],
      outputRange: [HEADER_MAX_HEIGHT * 2 / 3, 0],
      extrapolate: 'clamp',
    });

    const titleTextSize = this.scrollY.interpolate({
      inputRange: [0, HEADER_SCROLL_DISTANCE],
      outputRange: [32, 18],
      extrapolate: 'clamp',
    });

        // returned jsx
        {/* header */}
        <Animated.View style={[styles.header, { height: headerHeight }]}>
          <View style={styles.bar}>
            <Animated.Text
              style={[
                styles.title,
                { paddingTop: titleTopPadding, fontSize: titleTextSize },
              ]}
            >
              {I18n.t('EVENTS_LIST')}
            </Animated.Text>
          </View>
        </Animated.View>
        {/* list */}
        <Animated.View style={[styles.container]}>
          <SectionList
            data={events}
            sections={[{ title: '', data: events }]}
            scrollEventThrottle={1}
            onScroll={Animated.event([
              { nativeEvent: { contentOffset: { y: this.scrollY } } },
              // { useNativeDriver: true },
            ])}
            keyExtractor={this.eventsKeyExtractor}
            renderItem={this.renderEventsItem}
            indicatorStyle="default"
            renderSectionHeader={({ section }) => (
              <View style={{ height: HEADER_MAX_HEIGHT }} />
            )}
          />
        </Animated.View>

@heyman333
Copy link

@MacKentoch your code works very well despite setting {useNativeDriver: true}

@facebook facebook locked as resolved and limited conversation to collaborators Jun 2, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests