source react optimized index horizontal flatlist data code performance react-native react-native-flatlist

optimized - react native performance



¿Cómo mejorar el rendimiento de renderizado de FlatList para una lista grande con ReactNative 0.43? (4)

Estás recreando muchos objetos de estilo para cada fila de la lista individualmente. Esto pone mucho tráfico en el puente JS-> Native. Intente usar la hoja de estilo en lugar de pasar los estilos en línea.

Estoy tratando de representar una lista de ~ 250 imágenes en 3 columnas usando FlatList en RN0.43, y cambio el ancho de las imágenes en la función onLayout de FlatList para ajustar el ancho de la pantalla.

El rendimiento inicial está bien, pero después de un desplazamiento hacia arriba / abajo, a veces se tarda un segundo o 2 hasta que se muestran las imágenes.

es aún peor si cambio a la orientación de la pantalla, se tarda de 2 a 3 segundos en actualizarse.

algunos hallazgos:

  1. después de la rotación de la pantalla, toma un segundo o 2 hasta que se llama a FlatList.onLayout

  2. después de FlatList.onLayout y la actualización del ancho de la imagen, cada imagen (aproximadamente la mitad de la lista, ~ 150 imágenes; mientras solo se muestran ~ 15) se procesa 2 ~ 4 veces, mientras que render () solo se llama una vez.

pregunta:

  1. ¿Cómo puedo modificar el código para mejorar el rendimiento?
  2. en el getItemLayout () de una lista de columnas múltiples, ¿debería el desplazamiento ser algo como (itemHeight + separatorHeight) * (index% numColumns)?

Gracias.

probado en: GalaxySII (4.1.2) y Android SDK emulator (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> ); } }


Intente establecer una clave única para cada elemento usando keyExtractor

Por ejemplo:

render() { return ( <List> <FlatList ... keyExtractor={item => item.email} /> </List> ); }


Sí, estaba teniendo el mismo problema: varias imágenes y videos en la lista reaccionan de forma nativa. Así que eliminé la Lista Plana en lugar de esto. Preferí usar ListView para renderizar rápidamente y para solucionar el problema de toque en el elemento de la lista, pero No olvide configurar PureComponent con el elemento de la lista


Descargo de responsabilidad: Sé que la pregunta es antigua, pero aquí está mi respuesta de todos modos.

Mi aplicación tiene una mano llena de listas con más de 500 elementos. Entonces, llegamos a un punto en el que la aplicación se bloqueaba en los teléfonos populares que no están mal. Luego hice esta extensa investigación sobre el rendimiento en FlatLists.

El componente FlatList se presentó como una alternativa para el antiguo ScrollView . El problema es que ScrollViews renderiza toda tu lista a la vez para que se desempeñen mejor visualmente, pero existe un compromiso en el consumo de memoria, que conduce a bloqueos de aplicaciones.

Así que las listas planas son un mal necesario. Básicamente, solo representan elementos que son visibles, lo que es una gran ganancia en el consumo de memoria, pero un dolor para el rendimiento visual, especialmente para elementos pesados ​​/ complejos, que es su caso con esas imágenes sensibles.

¿Cómo solucionar?

Hay muchas estrategias que puede implementar para mitigar su problema.

  • Use imágenes en caché y de rendimiento, como react-native-fast-image . Todas las operaciones que puede eliminar o abreviar para liberar el subproceso de Javascript: hágalo (cada imagen es una new Image() , por lo tanto, si se almacenan en caché, tendrá su nombre de gancho loaded antes)

  • El componente del elemento de la lista es un componente de solo lectura, que se supone que es "tonto". Implemente un shouldComponentUpdate() { return false } o un método de control de actualización más sólido según sea necesario. Este es un gran aumento de perf.

  • Eliminar console.logs en cualquier lugar cerca de su lista. Ralentizan el hilo de Javascript realmente malo.

  • Construye tu aplicación para producción y pruébala. Casi siempre se vuelve dos o tres veces más rápido. Dev env es lento debido a la depuración.

  • Da a este artículo una buena lectura para más estrategias.

Conclusión

FlatList ES un componente lento. Este es un problema conocido, abierto y bien documentado . Haga lo que pueda para mejorarlo, y esperemos que las futuras versiones puedan solucionar este problema.