React 性能优化_性能优化React 性能优化 Profiler API React Profiler Optimizing Performance Performance



React 性能优化

Profiler API

Profiler 衡量React应用程序渲染的频率以及渲染的“成本”是多少。

其目的是帮助识别应用程序中速度较慢的部分,并可能从诸如memoization 之类的优化中受益。

⚠️ 分析会增加一些额外的开销, 因此在生产版本中将其禁用。

React 性能优化_React_02

React 性能优化_React Profiler_03

​https://reactjs.org/docs/profiler.html​

render(
<App>
<Profiler id="Navigation" onRender={callback}>
<Navigation {...props} />
</Profiler>
<Main {...props} />
</App>
);

render(
<App>
<Profiler id="Navigation" onRender={callback}>
<Navigation {...props} />
</Profiler>
<Profiler id="Main" onRender={callback}>
<Main {...props} />
</Profiler>
</App>
);

render(
<App>
<Profiler id="Panel" onRender={callback}>
<Panel {...props}>
<Profiler id="Content" onRender={callback}>
<Content {...props} />
</Profiler>
<Profiler id="PreviewPane" onRender={callback}>
<PreviewPane {...props} />
</Profiler>
</Panel>
</Profiler>
</App>
);

function onRenderCallback(
id, // the "id" prop of the Profiler tree that has just committed
phase, // either "mount" (if the tree just mounted) or "update" (if it re-rendered)
actualDuration, // time spent rendering the committed update
baseDuration, // estimated time to render the entire subtree without memoization
startTime, // when React began rendering this update
commitTime, // when React committed this update
interactions // the Set of interactions belonging to this update
) {
// Aggregate or log render timings...
}


React Profiler

​https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html​





​https://www.youtube.com/watch?v=00RoZflFE34​

Performance Tools

​https://reactjs.org/docs/perf.html​

Optimizing Performance

React 性能优化_性能优化

​https://reactjs.org/docs/optimizing-performance.html#use-the-production-build​

Webpack v4+ will minify your code by default in production mode.


const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
mode: 'production',
optimization: {
minimizer: [new TerserPlugin({ /* additional options here */ })],
},
};


shouldComponentUpdate

SCU

React 性能优化_React_05

// React.Component

class CounterButton extends React.Component {
constructor(props) {
super(props);
this.state = {count: 1};
}

shouldComponentUpdate(nextProps, nextState) {
if (this.props.color !== nextProps.color) {
return true;
}
if (this.state.count !== nextState.count) {
return true;
}
return false;
}

render() {
return (
<button
color={this.props.color}
onClick={() => this.setState(state => ({count: state.count + 1}))}>
Count: {this.state.count}
</button>
);
}
}


just inherit from ​​React.PureComponent​

// React.PureComponent

class CounterButton extends React.PureComponent {
constructor(props) {
super(props);
this.state = {count: 1};
}

render() {
return (
<button
color={this.props.color}
onClick={() => this.setState(state => ({count: state.count + 1}))}>
Count: {this.state.count}
</button>
);
}
}


Most of the time, you can use ​​React.PureComponent​​ instead of writing your own ​​shouldComponentUpdate​​.

它只会进行浅层比较,因此,如果道具或状态可能以浅层比较可能会丢失的方式被使用,则您将无法使用它。

update bug

class ListOfWords extends React.PureComponent {
render() {
return <div>{this.props.words.join(',')}</div>;
}
}

class WordAdder extends React.Component {
constructor(props) {
super(props);
this.state = {
words: ['marklar']
};
this.handleClick = this.handleClick.bind(this);
this.updateColorMap = this.updateColorMap.bind(this);
}

handleClick() {
// This section is bad style and causes a bug
const words = this.state.words;
words.push('marklar');
this.setState({words: words});
}

updateColorMap(colormap) {
colormap.right = 'blue';
}

render() {
return (
<div>
<button onClick={this.handleClick} />
<ListOfWords words={this.state.words} />
<button onClick={this. updateColorMap} />
</div>
);
}
}



solutions

  1. array update

handleClick() {
this.setState(state => ({
words: state.words.concat(['marklar'])
}));
}
handleClick() {
this.setState(state => ({
words: [...state.words, 'marklar'],
}));
};


  1. object update
function updateColorMap(colormap) {
return Object.assign({}, colormap, {right: 'blue'});
}

function updateColorMap(colormap) {
return {...colormap, right: 'blue'};
}


refs



​ ​