react function组件与class组件性能问题

react里面的function组件与class组件

假设场景是有一个父组件,包裹一个function子组件和class子组件

class组件在render过后,定义好的function,可以通过this.func进行调用,并且不会重新再创建

function组件会重新执行一遍,并且重新进行创建需要的function

对比起起来是否function组件在频繁刷新的地方,消耗的性能比class高?

阅读 5.3k
4 个回答

React官方文档也说了:

图片描述

简单测试一下:

const bench = require('benchmark')

const suite = new bench.Suite()

function myComp(i) {
  function foo() {
    return i + 1
  }
  return foo()
}

function staticFoo(i) {
    return i + 1
}

function myComp2(i) {
  return staticFoo(i)
}

suite
.add('closure create', () => {
  myComp(Math.random())
})
.add('static', () => {
  myComp2(Math.random())
})
.on('cycle', (evt) => {
  console.log(String(evt.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run()

执行结果

closure create x 46,013,919 ops/sec ±1.55% (91 runs sampled)
static x 46,724,334 ops/sec ±0.97% (89 runs sampled)
Fastest is static

毫无疑问静态函数是更快的一点的,但是差距非常小,实际应用场景几乎是可以忽略不计的。文档也提到Class本身也有一些额外的开销,而且很难被优化,所以基本可以抵销函数创建的开销了



那么闭包的复杂度也会影响创建的速度吗?还是跑下看下:

const bench = require('benchmark')

const suite = new bench.Suite()

function myComp(i) {
  function foo() {
    return i + 1
  }
}

function myComp2(i) {
  function complexFoo() {
    console.log(i)
    let j
    for(j = 0; j < i; j++) {
      console.log(i+j)
    }
    for(; j > 0; j--) {
      console.log(i+j)
    }
    return i+1
  }
}

suite
.add('simple', () => {
  myComp(Math.random())
})
.add('complex', () => {
  myComp2(Math.random())
})
.on('cycle', (evt) => {
  console.log(String(evt.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run()

运行结果:

simple x 45,947,495 ops/sec ±1.41% (87 runs sampled)
complex x 46,278,683 ops/sec ±1.33% (89 runs sampled)
Fastest is complex,simple

经过测试闭包的复杂度基本不会影响创建的效率。



所以可以放心使用Hook,只不过我们还可以做一些优化,比如:

  • 能否将函数提取为静态的
  • 简化组件的复杂度,动静分离
  • 再拆分更细粒度的组件,这些组件都使用React.memo缓存

如果组件内创建的function是callback function,不会有太大区别
如果是传给子组件的render function,可以用useCallback优化
性能上其实不会有太大区别,官方都不在意这些性能,现在官方文档示例里全是funciton组件
而且function可以对内部定义的函数名变量名压缩,Class没法对方法名field名压缩

使用useMemo

const { useMemo } from "react"
...
const { fn } = useMemo(() => {
    const fn = () => {}
    return { fn }
})
...
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏