@linux1s1s
2017-03-14T08:58:36.000000Z
字数 1732
阅读 1924
React-Native 2017-03
在RN中滚动视图包含两部分的内容【ScrollView】和【ListView】
废话不多少,直接上源码
import React, {Component} from 'react';import {ScrollView, AppRegistry, StyleSheet, Image, Text, View} from 'react-native';import {NavigationLayout as width} from "react-native/Libraries/NavigationExperimental/NavigationTypeDefinition";var styles = StyleSheet.create({scrollViewStyle: {backgroundColor: 'red',},itemStyle: {width: width,height: 200,},});var NwesomeProject = React.createClass({render(){return (<ScrollView style={styles.scrollViewStyle}>{this.renderItem()}</ScrollView>);},renderItem(){var itemArray = [];var colorArray = ['gray', 'green', 'blue', 'yellow', 'black', 'orange'];for (var i = 0; i < 60; i++) {itemArray.push(<View key={i} style={[styles.itemStyle, {backgroundColor: colorArray[i%6]}]}/>);}return itemArray;}});AppRegistry.registerComponent('NwesomeProject', () => NwesomeProject);
<ScrollView><Child1 /><Child2 />...</ScrollView>
它和 View 组件一样,可以包含一个或者多个子组件。对子组件的布局可以是垂直或者水平的,通过属性 horizontal=true/false 来控制。
为了检测性能问题,我们特意把列表拉长到60个,然后我们看看是不是RN-ScrollView无脑帮我们一直把子View添加到View树中

从上图看,屏幕中的子View个数正好和添加到ViewGroup的相等,所以可以推断,屏幕外的子 View,就被自动从 View 树中移除,这样可以提升性能。
但是,虽然ScrollView将当前不显示的View移出ViewGroup,但是还是将这些子View都初始化了,这将导致子View越多,渲染的时间和内存也会线性增加。

具体原因可以追踪代码,简单说结论是在RN-ScrollView中,所有的子 View 都是同时创建的。因此:RN 中的 ScrollView 并不像我们想象的那样高性能。
ListView是基于ScrollView的,并且做了一些优化,主要体现在ListView在初始化的时候默认初始10个子View,而并没有像ScrollView那么简单粗暴。
ListView 在第一次加载的时候,不论你的列表有多大,默认最多加载 initialListSize (默认10)个子项,所以能保证启动速度,如果还没有充满,或者在向下滑动过程中,再组件添加子项。这样的操作似乎比较合理,但是注意到,整个操作中,会逐渐向 ListView 中添加子项,新出现的子项,都是通过创建新的 View,而完全没有复用的过程。所以,如果在应用中,ListView 中的子项数量特别多,ListView 往下滑动的过程中,内存会逐渐上涨的。
react-native-sglistview这个并没有从本质上解决问题,而是将不用的View退化为普通的子View