2016-03-30 6 views
1

Welche Best Practices sind für das Rendering eines Image-basierten Newsfeeds in der nativen Reaktion angezeigt?React Native: performantes Rendering eines imagebasierten Newsfeeds

Ich habe einen sehr einfachen Newsfeed, bei dem jede Geschichte ein Titelbild und dann eine Sternenbewertung (bestehend aus 1-5 Bildern) hat. Beim ersten Rendern scheinen die Bilder in zufälliger Reihenfolge geladen zu sein und es sieht schrecklich und nicht nativ aus.

Here's a 7s video showing the screen transition and render.

Gibt es eine Möglichkeit zur Steuerung der Reihenfolge, in der die Bilder machen, oder nicht eine Geschichte, bis der gesamte Block geladen zu machen?

Wenn es hilft, ist der Code unten. Verwenden von IncrementalListView zum Rendern der Zeilen. Release Build, iOS 9.3, iPhone 6. Jedes Titelbild ist ~ 55kb JPG und der Stern ist ~ 3kb PNG. Beide Bilder sind im Bundle enthalten.

UPDATE 3/31

änderte ich den Code IncrementalListView zu verwenden, anstatt direkt in Scroll von Rendering, aber das hat nicht geholfen. Das Problem scheint darin zu liegen, wie Bilder dekodiert und gerendert werden und nicht mit der Art, wie Zeilen gerendert werden.

class DiscoverRow extends React.Component { 
    render() { 
    let images = { 
     wide: { 
     data: require('../img/img-wide.jpg'), 
     height: 200, 
     width: 376 
     } 
    }; 
    let title = this.props.event.name; 
    let date = "Tomorrow"; 
    let place = this.props.event.venue.name; 
    const newHeight = images.wide.height/images.wide.width * screenWidth; 
    return (

     <View style={[rowStyles.cell]}> 
      <View style={{ borderRadius: 15 }}> 
      <Image resizeMode={'stretch'} source={images.wide.data} style={[rowStyles.thumbnail]} /> 
      <View style={[rowStyles.annotationsContainer]}> 
       <View style={rowStyles.textContainer}> 
       <AHStarRating starColor={gConstants.themeColor} disabled rating={4.5} style={{ width: 100 }} /> 
       <AHText style={rowStyles.title}>{title}</AHText> 
       <AHText style={rowStyles.date}>{date}</AHText> 
       </View> 
       <View style={rowStyles.commentsContainer}> 
       <Image source={require('../img/chat.png')} 
        style={{ width: 36, height: 36, 
        tintColor: gConstants.themeColor, 
        backgroundColor: 'transparent' }} 
       /> 
       <TouchableWithoutFeedback onPress={this._poop}> 
        <Image 
        source={require('../img/heart.png')} 
        style={{ width: 36, height: 36, 
         tintColor: gConstants.themeColor, 
         backgroundColor: 'transparent' }} 
        /> 
       </TouchableWithoutFeedback> 
       </View> 
      </View> 
      </View> 
     </View> 
    ); 
    } 
} 

class DiscoverPage extends React.Component { 

    static relay = { 
    queries: { viewer:() => Relay.QL`query { viewer }` }, 
    fragments: { 
     viewer:() => Relay.QL` 
     fragment on Viewer { 
      events { 
      id 
      name 
      venue { 
       name 
      } 
      } 
     } 
     `, 
    }, 
    }; 

    componentDidMount() { 
    InteractionManager.runAfterInteractions(() => { 
     this.setState({ renderPlaceholderOnly: false }); 
    }); 
    } 

    componentWillReceiveProps(nextProps) { 
    if (!nextProps.relayLoading) { 
     const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); 
     this.setState({ 
     dataSource: ds.cloneWithRows(nextProps.viewer.events), 
     }); 
    } 
    } 

    _renderRow(event: Object, sectionID: number, rowID: number) { 
     return <DiscoverRow 
     onPress={() => Actions.event({ event })} 
     key={`comment-${rowID}`} event={event} 
     />; 
    } 

    render() { 
    if (this.props.relayLoading || this.state.renderPlaceholderOnly) { 
     return <View><AHText>Relay loading</AHText></View>; 
    } else { 
     return (
     <View style={styles.container}> 
      <AHNavBar title={'Discover'} leftTitle={""} rightImage={require('../img/filter.png')} /> 
      <IncrementalListView 
      initialListSize={3} 
      dataSource={this.state.dataSource} 
      renderRow={this._renderRow} 
      renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} 
      style={styles.separator} />} 
      /> 
     </View> 
    ); 
    } 
    } 
} 
+0

Haben Sie versucht, mit [ListView] (http://facebook.github.io/react-native/docs/listview.html) anstelle von [ScrollView] zu implementieren (http://facebook.github.io/react-native) /docs/scrollview.html)? –

+0

Das war eine großartige Idee, danke, aber es bewegte die Nadel w.r.t. die Bildladegeschwindigkeit. Siehe aktualisierten Code – emrosenf

Antwort

0

Sie sollten mit einem ListView anstelle eines ScrollView implementieren. ListView verfügt über Leistungsoptimierungen, die die Bildlaufleistung verbessern.

Vom ListView Abschnitt im React Native Docs:

Es gibt ein paar Performance-Operationen entworfen Listview Scroll glatt zu machen, während dynamisch potenziell sehr große Belastung (oder konzeptionell unendlich) Datensätze

+0

Danke für den Vorschlag. Ich habe versucht, ListView und IncrementalListView @ notbrent, keine große Verbesserung. Ich aktualisiere meinen Code oben auf den neuesten, den ich verwende. – emrosenf

+0

Ich nehme an, Sie sehen immer noch die Leistungsprobleme in einem Release-Build? Ich stoße häufig auf Leistungsprobleme im Entwicklungsmodus, die in Release-Builds nicht vorhanden sind. –

+0

Ja, bin ich. [Ich habe ein neues Video hochgeladen] (https://vid.me/qu7m), das zeigt, wie es derzeit aussieht, iOS 9.3, iPhone 6, Release-Build. Es ist etwas verbessert gegenüber dem vorherigen, aber es sieht immer noch entschieden nicht-nativ aus. – emrosenf