react 项目关于性能优化
1.在页面加载的时候,会渲染render()下面的标签,会造成在不必要的情况下被调用render.
组件渲染的过程中,有时候并没用到props或者state的值,或者组件的props或者state并没有在父组件重新绘染时发生改变。这意味着重新绘染这个组件会得到和已知虚拟DOM一模一样的结果。可以通过shouldComponentUpdate来控制。
关于shouldComponentUpdate:
组件更新生命周期中必调用shouldComponentUpdate,字面意思是组件是否应该更新。shouldComponentUpdate默认返回true,必定更新。所有当我们判断出组件没必要更新时,shouldComponentUpdate可以返回false,就达到优化效果。
shouldComponentUpdate生命周期有俩个参数,一个是nextProps,另一个是nextState,而我们就用这俩个上一次的props和state与这一次的props和state去做比较,如果俩者相同,那么就return false,不让它进行更新就可以了。
简单示例:
shouldComponentUpdate(nextProps,nextState) {
if (nextProps === this.props && nextState === this.state)
return false
return true
}
项目中遇到的具体示例:
import React from 'react';
import { Spin } from 'antd';
import isEqual from 'lodash/isEqual';
import { isComponentClass } from './Secured'; // eslint-disable-next-line import/no-cycle
export default class PromiseRender extends React.Component {
state = {
component: () => null,
};
componentDidMount() {
this.setRenderComponent(this.props);
}
shouldComponentUpdate = (nextProps, nextState) => {
const { component } = this.state;
if (!isEqual(nextProps, this.props)) {
this.setRenderComponent(nextProps);
}
if (nextState.component !== component) return true;
return false;
}; // set render Component : ok or error
setRenderComponent(props) {
const ok = this.checkIsInstantiation(props.ok);
const error = this.checkIsInstantiation(props.error);
props.promise
.then(() => {
this.setState({
component: ok,
});
return true;
})
.catch(() => {
this.setState({
component: error,
});
});
} // Determine whether the incoming component has been instantiated
// AuthorizedRoute is already instantiated
// Authorized render is already instantiated, children is no instantiated
// Secured is not instantiated
checkIsInstantiation = target => {
if (isComponentClass(target)) {
const Target = target;
return props => <Target {...props} />;
}
if (React.isValidElement(target)) {
return props => React.cloneElement(target, props);
}
return () => target;
};
render() {
const { component: Component } = this.state;
const { ok, error, promise, ...rest } = this.props;
return Component ? (
<Component {...rest} />
) : (
<div
style={{
width: '100%',
height: '100%',
margin: 'auto',
paddingTop: 50,
textAlign: 'center',
}}
>
<Spin size="large" />
</div>
);
}
}
2.调整CSS而不是强制组件加载和卸载
尽量的减少组件的创建和销毁,这样对于性能还是有一定的损耗的,我们可以将组件隐藏掉,比如加hidden属性,控制css的display、opacity、visibility等等隐式隐藏的方法。
3.使用React.Fragment或者一个空标签避免添加额外的DOM
4.传参优化
React中,组件嵌套是十分常见的,在父组件往子组件传递对象时,应该将对象的key和value在render()内先定义再使用,不然每一次使用子组件时都会生成新的对象进行传递。
切记将props/state以展开形式传递给子组件,除非子组件需要用到父组件的所有props/state