如何确定React Native代码中的JS瓶颈?

时间:2017-08-21 20:59:14

标签: performance react-native performance-testing

我正在向现有应用添加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行)如下所示:

printWasted

我不知道"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>
    )
  }

0 个答案:

没有答案