我正在向现有应用添加React Native Slider组件,并且更喜欢使用其onValueChange
道具,以便当用户向左和向右滑动旋钮时,有几个Text组件有它们的更新的值以响应Slider的当前值。
首次尝试时,在松开滑块旋钮后会产生大量延迟。 StackOverflow不允许我在这里嵌入gif,所以我将保留链接:http://imgur.com/sEowpZt
当我注释掉onValueChange
并使用onSlidingComplete
时,根本没有延迟,但是两个文本组件在滑动停止之前不会更新其值,这会降低效果。我怀疑setState
内部的onValueChange
次呼叫堆积速度比处理/完成它们的速度快,并且与我的应用程序的其他部分有关。为了确认这一点,我通过react-native init
创建了一个新的反应原生应用,在代码中添加了相同的_renderNameYourPriceModal()
,在屏幕上包含一个按钮以打开它,并发现根本没有延迟:{ {3}}
如何确定减缓现有应用的setState
次调用的速度?我发现了http://imgur.com/iZnvDML,我正在使用它来在Chrome开发者控制台中打印一个摘要表。
import Perf from 'react-native/Libraries/Renderer/shims/ReactPerf'
...
componentDidMount() {
setTimeout(() => {
Perf.start()
setTimeout(() => {
Perf.stop()
const measurements = Perf.getLastMeasurements()
Perf.printWasted(measurements)
}, 7000)
}, 1000)
}
根据React Perf tool的Perf文档:
printWasted()
Perf.printWasted(measurements)
探查器最有用的部分。
“浪费”时间花在没有实际呈现的组件上 什么,例如渲染保持不变,因此没有触及DOM。
但我不确定如何解释结果以进行必要的更改。例如,运行我的应用程序时,该表的前四行(总共有24行)如下所示:
我不知道"ItemDetailsScreen > View"
列中的第一行Owner > Component
指的是哪个视图,因为仅在该屏幕上有20多个视图。对于进一步的上下文,我使用的是React-Navigation,这是StackNavigator中的嵌套屏幕,虽然我没有看到对此屏幕状态的更新如何导致在层次结构中的屏幕上重新渲染。是否有必要将此屏幕进一步分解为更多自定义子组件,以便覆盖shouldComponentUpdate
,或者printWasted
结果确切地告知哪些区域有问题?
这是我使用Slider返回Modal的函数:
_renderNameYourPriceModal() {
var likelihood = 'Possible'
var lowestVal = 5
var highestVal = 15
if (this.state.nypValue < 6) {
likelihood = 'Nearly Impossible'
} else if (this.state.nypValue < 8) {
likelihood = 'Highly Unlikely'
} else if (this.state.nypValue < 10) {
likelihood = 'Unlikely'
}
return (
<Modal
onRequestClose={() => { this.setState({nypModalVisible: false})}}
animationType={"fade"}
transparent={true}
visible={this.state.nypModalVisible}>
<View style={{paddingTop: 22, height: Dimensions.get('window').height, backgroundColor: 'rgba(252,84,102,0.9)', alignItems: 'center', justifyContent: 'center'}}>
<View
style={{
height: Dimensions.get('window').height * 0.5,
width: Dimensions.get('window').width * 0.9,
backgroundColor: 'white',
borderRadius: 10,
alignItems: 'center'
}}>
<View
style={{flex: 0.8, alignItems: 'center', justifyContent: 'center'}}>
<View style={{flex: 0.25, flexDirection: 'row', width: Dimensions.get('window').width * 0.97, top: -10, alignItems: 'flex-start', justifyContent: 'center'}}>
<View style={{flex: 0.1}}></View>
<View style={{flex: 0.8, alignSelf: 'center', alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 23}}>Name Your Price</Text>
</View>
<View style={{flex: 0.1, top: -5, height: 40, alignItems: 'flex-end', justifyContent: 'flex-end'}}>
<TouchableHighlight
underlayColor={'gray'}
style={{height: 40, width: 40, backgroundColor: 'gray', borderRadius: 20, alignItems: 'center', justifyContent: 'center'}}
onPress={() => {
// close
this.setState({nypModalVisible: false})
}}>
<Text style={{fontSize: 25, color: 'white'}}>X</Text>
</TouchableHighlight>
</View>
</View>
<View style={{flex: 0.25, width: Dimensions.get('window').width * 0.8, alignItems: 'center', justifyContent: 'flex-start'}}>
<View style={{flex: 0.5, flexDirection: 'row', alignItems: 'center', justifyContent: 'center'}}>
<View style={{flex: 0.2, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 19}}>${lowestVal.toFixed(2)}</Text>
</View>
<View style={{flex: 0.6, alignItems: 'center', justifyContent: 'center'}}>
<Slider
style={{width: Dimensions.get('window').width * 0.5}}
maximumValue={15}
minimumValue={5}
step={0.5}
value={this.state.nypValue}
// onSlidingComplete={(val) => {
// this.setState({nypValue: val})
// }}
onValueChange={(val) => {
// change value here
this.setState({nypValue: val})
}}
/>
</View>
<View style={{flex: 0.2, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 19}}>${highestVal.toFixed(2)}</Text>
</View>
</View>
<Text>${this.state.nypValue.toFixed(2)}</Text>
<Text>Likelihood: {likelihood}</Text>
</View>
<View style={{flex: 0.5, paddingTop: 20, alignItems: 'center', justifyContent: 'flex-start', paddingHorizontal: 10}}>
<Text style={{textAlign: 'center', top: 25, fontSize: 18}}>Let us know the price you'd like to see this item drop to, and we'll let YOU know when it does!</Text>
</View>
</View>
<View style={{flex: 0.2, alignItems: 'center', justifyContent: 'center'}}>
<TouchableHighlight
style={{height: 50, width: Dimensions.get('window').width * 0.8, alignItems: 'center', justifyContent: 'center', backgroundColor: '#70a8ff', borderRadius: 5}}
underlayColor={'#70a8ff'}
onPress={() => { }}>
<Text style={{fontSize: 20, color: 'white'}}>Set Price Alert</Text>
</TouchableHighlight>
</View>
</View>
</View>
</Modal>
)
}