ReactJS-内联箭头功能性能

时间:2020-09-29 10:21:18

标签: javascript reactjs performance react-native

我已经阅读到,使用箭头函数内联会在每个重新渲染的组件上重新创建该函数,从而导致性能问题。

在我的代码中,我遇到这种情况

render() {
   return (
       <View
          onLayout={(event) => {
             this.itemHeights[index] = event.nativeEvent.layout.height;
          }}  
       >
     ...
   )
 }

我曾想过做这样的事情以获得更好的性能:

getItemHeight = (index, {nativeEvent: {layout: {height}}}) => this.itemHeights[index] = event.nativeEvent.layout.height;

render() {
   return (
       <View
          onLayout={(event) => getItemHeight(index, event)}  
       >
     ...
   )
 }

但是我不确定这是否更好...我必须在内联函数中调用一个函数。我这样做是因为我需要参数索引,所以我做不到:

 <View
    onLayout={getItemHeight}  
 >

我知道这可能并不太昂贵,但是对于我的用例来说,这是非常昂贵的,因为我必须即时重新渲染项目。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

声明与执行

首先,我认为您在这里混淆了两件事。 函数的声明与函数的执行有所不同。

该组件也不会一直重新渲染,只是因为在render函数return中重新声明了一个函数。

在函数的声明与其执行之间的性能影响之间也存在巨大差异。

参考稳定函数与内联函数

因此,在第一个示例中,您正在做的是为View组件声明一个函数。基本上,这会重置onLayout道具的值,因为内联函数不是参照稳定的。

~~在第二个示例中(我认为这是一个类组件),您使用的是参照稳定函数,因此onLayout的prop值保持不变。~~

更新:实际上这是不对的,我不好。您仍在使用不稳定函数。但是您可以像这样将其作为班级成员提出来:

public getItemHeight(index, {nativeEvent: {layout: {height}}}) { 
  this.itemHeights[index] = event.nativeEvent.layout.height;
}

// ...
// ... inside the render function:
return {
  <View onLayout={this.getItemHeight}></View>
}

但是我不确定这是否更好...我必须在内联函数中调用一个函数。我这样做是因为我需要参数索引,所以我做不到:

实际上,这种说法是不正确的。您还可以使用上面定义的函数检索索引。 使用此代码,您只是为prop提供了对要由回调调用的函数的引用。这将很好地填充参数。

何时重新渲染组件?

当属性或状态发生更改时,组件将重新呈现。 因此,在您的第一个示例中,View组件仅在必须重新渲染父组件时才会重新渲染。因此,父级渲染并评估其子组件。这确实会触发View组件的渲染功能,并将功能换成onLayout

在第二个示例中(考虑到上面建议的代码更改),View组件不会触发其渲染功能,因为onLayout的prop值未更改。

但这并不意味着您的第一个示例必然导致DOM更改并重新绘制(这是React内部的另一种算法)。 DOM更改将是真正昂贵的部分。

渲染与重绘

Rerender是React在内部运行的进程。 React只是触发了必须重新渲染的组件的渲染功能。但是只有在生成的DOM与以前不同的情况下,才会在运行时在实际页面内进行重新绘制。

您可以在React Docs中进一步了解此内容:https://reactjs.org/docs/reconciliation.html

那么什么时候需要使用参照稳定函数?

我认为您不应该过早地优化此类内容。它会使代码更加膨胀,并引入并非总是必需的复杂性。

这里也有一个完整的部分:https://reactjs.org/docs/optimizing-performance.html#avoid-reconciliation

如果不消耗您的性能,为什么还要麻烦进行微优化呢? 仅仅因为您阅读到每次都会重新创建内联函数(顺便说一句,这也适用于非箭头函数。正是内联声明使它每次都重新创建),因此每次都会渲染函数,这并不总是意味着React必须重新粉刷或者对性能有很大影响。

因此,即使在没有问题的情况下,也不要过早地在小小的性能提升上摆弄。

基于React的应用程序是巨大的代码野兽。一旦遇到性能问题,就会有很多大问题需要解决。