Skip to content

[Flatlist] getItemLayout fires multiple times upon every frame scrolled manually #20467

@newah

Description

@newah

Environment

Environment:
OS: macOS High Sierra 10.13.6
Node: 8.9.4
Yarn: 1.3.2
npm: 5.5.1
Watchman: 4.9.0
Xcode: Xcode 9.4.1 Build version 9F2000
Android Studio: 3.0 AI-171.4443003

Packages: (wanted => installed)
react: 16.4.0 => 16.4.0
react-native: ^0.55.4 => 0.55.4

iOS

Description

Without getItemLayout flatlist works as expected - fast. With getItemLayout we started noticing rows aren't loading instantly when scrolling manually. After removing getItemLayout performance is good again.

We are using shouldComponentUpdate (also tried PureComponent).

In the gif you can see logs that getItemLayout is firing constantly when using flatlist manually - which seems to be why performance is suffering. Is this to be expected?

ezgif com-video-to-gif

Reproducible Demo

Simplified my use-case with reusing part of someone else's demo :)

class MyListItem extends React.PureComponent {
    render() {
        return (
            <View
                style={{
                    paddingVertical: 10,
                }}>
                <TouchableOpacity onPress={() => null}>
                    <Text
                        style={{
                            color: '#000',
                            height: 40,
                            justifyContent: 'center'
                        }}>
                        lalalalaal
                      </Text>
                </TouchableOpacity>
            </View>
        )
    }
}

_renderItem = ({ item }) => (
    <MyListItem
        produto={item.produto}
    />
);

render() {
                    return <FlatList
                    data={['one', 'two', 'three', 'one', 'two', 'three', 'one', 'two', 'three', 'one', 'two', 'three', 'one', 'two', 'three', 'one', 'two', 'three', 'one', 'two', 'three', 'one', 'two', 'three', 'one', 'two', 'three', 'one', 'two', 'three']}
                    showsVerticalScrollIndicator={false}
                    initialListSize={4}
                    renderItem={_renderItem}
                    keyExtractor={(item, index) => '' + index}
                    ref={(ref) => { this.flatListRef = ref }}
                    getItemLayout={(data, index) => {
                        console.log("get item layout " + index)
                        return { length: 40, offset: 40 * index, index }
                    }}
                />
}

Expected behavior

getItemLayout only fires when scrollToIndex or similar methods are fired. Or at most when rows are actually re-rendering - though it doesn't look like it's used when simply rendering visible rows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Ran CommandsOne of our bots successfully processed a command.Resolution: LockedThis issue was locked by the bot.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions