admin管理员组文章数量:1323707
So I finished reading this article which basically talks about how v8 and other javascript engines internally cache the "shape" of objects so that when they need to repeatedly access a particular property on an object, they can just use the direct memory address instead of looking up where in that object's memory that particular property is.
That got me thinking, in React you often declare a ponent's state inside the constructor but don't include all the properties that will eventually be included in the state, for example:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
hasLoaded: false
};
}
ponentDidMount() {
someAjaxRequest.then((response) => {
this.setState({
content: response.body,
hasLoaded: true
});
});
}
render() {
return this.state.hasLoaded ?
<div>{this.state.content}</div> :
<div>Loading...</div>;
}
}
Since according to the article, the state object doesn't remain a consistent structure, would doing something like this be less efficient than defining all the possible state's fields in the constructor? Should you always at least add all the properties even giving them a value of null
so that the object is always consistent? Will it impact performance in any substantial way?
So I finished reading this article which basically talks about how v8 and other javascript engines internally cache the "shape" of objects so that when they need to repeatedly access a particular property on an object, they can just use the direct memory address instead of looking up where in that object's memory that particular property is.
That got me thinking, in React you often declare a ponent's state inside the constructor but don't include all the properties that will eventually be included in the state, for example:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
hasLoaded: false
};
}
ponentDidMount() {
someAjaxRequest.then((response) => {
this.setState({
content: response.body,
hasLoaded: true
});
});
}
render() {
return this.state.hasLoaded ?
<div>{this.state.content}</div> :
<div>Loading...</div>;
}
}
Since according to the article, the state object doesn't remain a consistent structure, would doing something like this be less efficient than defining all the possible state's fields in the constructor? Should you always at least add all the properties even giving them a value of null
so that the object is always consistent? Will it impact performance in any substantial way?
- 2 This is something you could test yourself by doing some benchmarks. In my experience it results indeed in faster execution if all properties are created in the constructor. – trincot Commented Jul 13, 2018 at 21:30
- 8 Not to mention it will be easier for your colleagues and yourself in 6 months to grasp what will be present in your state if you have default values. Win-win. – Tholle Commented Jul 13, 2018 at 21:32
4 Answers
Reset to default 5 +50TL;DR The performance wins seem to be negligible enough to not really be worth it.
Test setup:
I made 100,000 children of this class:
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,
};
}
ponentDidMount() {
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;
The children are made as follows:
const children = [];
for (let i = 0; i < 1 * 100 * 1000; i++) {
children.push(<Child display={true} numKeys={1000} key={i} />);
}
return (
<div>
{children}
</div>
);
The idea being: I could pass in the display
prop to either render the same HTML for every child, or a different HTML.
I also passed in a numKeys
to determine how many different types of keys there should be on the object. After testing, the display
prop didn't significantly affect the DOM render time, so I didn't report it below. All tests were run with yarn build && serve -s build
via create-react-app
Results
Same key for all children
3 keys for all children
10 keys for all children
1000 keys for all children
*all tests in Chrome 67.0.3396.99
As you can see, the performance for 100,000 objects is negligible until you have a lot of different shaped objects. Even then, your performance increase is 700ms over 100,000 ponents, or 7 microseconds per ponent. It's certainly not the 8x speedup claimed.
MOREOVER: Your render time is likely to be dwarfed by DOM actions in anything realistic, and not synthetic like this test.
Optimizations aside, it's a good idea to model all local state fields even if it's just data: null
as you mention. This way, you can reset the ponent back to it's initial state with a simple call to this.setState
.
For optimization and better performance it is always remend to initialize all the ponents variables in constructor so the ponent is loaded with initial values and creation of new state variables can be avoid at run time.
the main reason to define all properties upfront is that it serves as a self documenting
feature of your ponent.
So
- it reduces the need to add ments
- it reduces the time it takes for a developer to familiarise him/herself with the ponent
the long term time/maintenance gains in doing this will pay for itself, performance gains aside.
版权声明:本文标题:javascript - Should you define all properties of a component's state inside the constructor? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742130344a2422129.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论