1

react里面的function组件与class组件

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

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

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

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

Radis 7
7月2日提问

查看全部 4 个回答

0

已采纳

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缓存
1

我刚开始写React hooks时也有这个顾虑,函数式组件每次渲染里面的闭包都要重新创建,不会很耗性能吗? 类组件的方法是静态不变的,那是否在这点上类组件性能更好一点?

上面的答案其实已经说得很明白了,目前而言,实现同样的功能,类组件和函数组件的效率是不相上下的。但是函数组件是未来,而且还有优化空间,React团队会继续优化它。而类组件会逐渐退出历史

要不, 再跑个测试看看:

const React = require('react')
const ReactDOM = require('react-dom/server.node')
const bench = require('benchmark')
process.env.NODE_ENV === 'production'

const suite = new bench.Suite()

function Func(){
  return React.createElement('span', {onClick: () => {console.log('click') }}, 'children')
}

class Cls extends React.Component{
  handleP() {
    console.log('click')
  }

  render(){
   return React.createElement('span', {onClick: this.handleP}, 'children')  
  }
}

suite
.add('function component', () => {
  ReactDOM.renderToString(React.createElement(Func))
})
.add('class component', () => {
  ReactDOM.renderToString(React.createElement(Cls))
})
.on('cycle', (evt) => {
  console.log(String(evt.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run()

我跑了几次,结果如下,不分伯仲:

D:\home\workspace\playground>node class-vs-func.js
function component x 143,556 ops/sec ±8.58% (89 runs sampled)
class component x 143,543 ops/sec ±7.58% (86 runs sampled)Fastest is class component,function component

D:\home\workspace\playground>node class-vs-func.js
function component x 151,240 ops/sec ±1.84% (87 runs sampled)
class component x 150,126 ops/sec ±2.96% (81 runs sampled)
Fastest is function component,class component

D:\home\workspace\playground>node class-vs-func.js
function component x 132,336 ops/sec ±8.49% (86 runs sampled)
class component x 142,621 ops/sec ±2.95% (88 runs sampled)
Fastest is class component

D:\home\workspace\playground>node class-vs-func.js
function component x 145,461 ops/sec ±3.41% (86 runs sampled)
class component x 137,405 ops/sec ±6.83% (81 runs sampled)
Fastest is function component,class component

荒山 · 7月9日

展开评论

推荐答案

1

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

推广链接