您应该在构造函数中定义组件状态的所有属性吗?

Mar*_*ode 10 javascript v8 reactjs

所以我读完了这篇文章,主要讨论了v8和其他javascript引擎如何在内部缓存对象的"形状",以便当他们需要重复访问对象的特定属性时,他们可以只使用直接内存地址而不是查找在该对象的内存中特定属性的位置.

这让我想到,在React中,你经常在构造函数中声明组件的状态,但不包括最终将包含在状态中的所有属性,例如:

class MyComponent extends React.Component {
   constructor(props) {
       super(props);
       this.state = {
          hasLoaded: false
       };
   }

   componentDidMount() {
       someAjaxRequest.then((response) => {
           this.setState({
              content: response.body,
              hasLoaded: true
           });
       });
   }

   render() {
       return this.state.hasLoaded ?
          <div>{this.state.content}</div> :
          <div>Loading...</div>;
   }
}
Run Code Online (Sandbox Code Playgroud)

因为根据文章,状态对象不是一致的结构,这样做会比定义构造函数中所有可能的状态字段效率低吗?你是否应该总是至少添加所有属性,甚至给它们一个值,null使对象始终保持一致?它会以任何实质性方式影响性能吗?

Ani*_*ift 5

TL; DR表现胜利似乎可以忽略不计,真的不值得.

测试设置:

我养了这个班的10万个孩子:

import React, { Component } from 'react';

const getRand = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

class Child extends Component {
  constructor() {
    super();
    this.state = {
      loading: false,
    };
  }

  componentDidMount() {
    const key = getRand(1, this.props.numKeys);
    this.setState({
      key,
      [key]: 'bar',
    });
  }

  render() {
    if (this.props.display) {
      return <div>child {this.state.key} {this.state[this.state.key]}</div>
    }
    return <div>child 0</div>
  }
}

export default Child;
Run Code Online (Sandbox Code Playgroud)

孩子们的制作如下:

const children = [];
for (let i = 0; i < 1 * 100 * 1000; i++) {
  children.push(<Child display={true} numKeys={1000} key={i} />);
}
return (
  <div>
    {children}
  </div>
);
Run Code Online (Sandbox Code Playgroud)

我的想法是:我可以传递display道具,为每个孩子或不同的HTML呈现相同的HTML.

我还传入了一个numKeys来确定对象上应该有多少种不同类型的键.经过测试,display道具没有显着影响DOM渲染时间,所以我没有在下面报告.所有测试均使用yarn build && serve -s buildvia 运行create-react-app

结果

所有孩子的同一把钥匙

所有孩子的同一把钥匙

所有孩子的3把钥匙

所有孩子的3把钥匙

所有孩子的10把钥匙

所有孩子的10把钥匙

所有孩子的1000把钥匙

所有孩子的1000把钥匙 *Chrome 67.0.3396.99中的所有测试

如您所见,在您拥有许多不同形状的对象之前,100,000个对象的性能可以忽略不计.即使这样,您的性能提升超过100,000个组件700毫秒,或每个组件7微秒.这肯定不是8倍的加速宣称.

更多:你的渲染时间可能会被任何现实中的DOM动作相形见绌,而不像这个测试那样合成.