19

RN0.43 で FlatList を使用して 3 列に ~250 個の画像のリストをレンダリングしようとしています。FlatList の onLayout 関数で画像の幅を画面の幅に合わせて変更します。

初期のパフォーマンスは問題ありませんが、上下にスクロールした後、画像が表示されるまでに 1 ~ 2 秒かかることがあります。

画面の向きを変更するとさらに悪いことに、画面が更新されるまでに 2 ~ 3 秒かかります。

いくつかの調査結果:

  1. 画面の回転後、FlatList.onLayout が呼び出されるまでに 1 ~ 2 秒かかります

  2. FlatList.onLayout と画像幅の更新の後、各画像 (リストの約半分、最大 150 個の画像。表示されるのは最大 15 個のみ) は 2 ~ 4 回レンダリングされますが、render() は 1 回だけ呼び出されます。

質問:

  1. コードを変更してパフォーマンスを改善するにはどうすればよいですか?
  2. 複数列リストの getItemLayout() では、オフセットは (itemHeight + separatorHeight) * (index%numColumns) のようにする必要がありますか?

ありがとう。

テスト対象: GalaxySII (4.1.2) および Android SDK エミュレーター (7.1.1)

var data = [
    require('./res/img/Search.png'),
    require('./res/img/test - Copy.png'),
    // ~250 items
    ...];

class app extends React.Component {
    renderItem (info, width) {
        console.log('renderItem', info.index);
        if(width !== this.width) {
            this.imageStyle = {width: width-MarginHorizontal , height: width-MarginHorizontal, resizeMode: 'contain'};
        }
        return (
            <Image
                source = {info.item}
                key = {info.index}
                style={this.imageStyle}/>
            );
    }

    render() {
        console.log('Test.render');
        return (
            <View style={{
                flex: 1,
                flexDirection: 'row',
                justifyContent: 'flex-start',
                alignItems: 'center',
                backgroundColor: '#F5FCFF'
            }}>
                <GridList
                    numColumns={3}
                    columnWrapperStyle={{ alignItems: 'center', marginVertical: 5, justifyContent: 'space-around'}}
                    data={data}
                    renderItem={this.renderItem}
                />
            </View>
        );
    }
}

class GridList extends Component {
    onLayout(event) {
        console.log('GridList.onLayout()');
        let newColumnWidth = event.nativeEvent.layout.width/ this.numColumns;
        this.layout = Object.assign({},event.nativeEvent.layout);
        if( undefined === this.columnWidth  || Math.abs(newColumnWidth - this.columnWidth) > WidthTolerance ) {
            this.columnWidth = newColumnWidth;
            if(this.isComponentMounted) {
                this.setState({renderCount: this.state.renderCount+1});
            } else {
                this.state.renderCount +=1;
            }
        }
    }
    render() {
        console.log('GridList.render()');
        return (
            <FlatList
                {...(this.modifiedProps)}
                renderItem={(info) => { return this.props.renderItem(info, this.columnWidth); }}>
                {this.props.children}
            </FlatList>
        );
    }
}
4

5 に答える 5

-1

keyExtractorを使用して各アイテムに一意のキーを設定してみてください

例えば:

render() {
  return (
    <List>
      <FlatList
        ...
        keyExtractor={item => item.email}
      />
    </List>
  );
}
于 2017-11-10T15:22:48.870 に答える