目录
1.render里面尽量减少新建变量和bind函数,传递参数是尽量减少传递参数的数量。
1.render里面尽量减少新建变量和bind函数,传递参数是尽量减少传递参数的数量。
第一种是在构造函数中绑定this,构造函数每次渲染只会执行一遍;
第二种是在render()函数里绑定this,每次render()都会重新执行一遍函数;
第三种使用箭头函数,每次render()都会生成一个新的箭头函数
react判断是否需要进行render是浅层比较
2.定制shouldComponentUpdate函数
3.使用React.PureComponent
React.PureComponent 与 React.Component 很相似。两者的区别在于 React.Component 并未实现 shouldComponentUpdate(),而 React.PureComponent 中以浅层对比 prop 和 state 的方式来实现了该函数。
React.PureComponent 中的 shouldComponentUpdate() 将跳过所有子组件树的 prop 更新。因此,请确保所有子组件也都是“纯”的组件。
使用PureComponent的一个前提:组件在相同 props
传入值的情况下总会有相同的渲染内容。(类似纯函数的定义:传入相同的参数执行后,总会得到相同的返回值)
从另一个方面来说,就是 PureComponent
跳过渲染时,它的所有子组件也会跳过渲染,即使子组件应被更新,所以需要保证纯组件的所有子组件也都是纯组件。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
date: new Date(),
};
}
componentDidMount() {
setInterval(() => {
this.setState({
date: new Date(),
});
}, 1000);
}
render() {
return (
<div>
<div>{this.state.date.toString()}</div>
<B seconds={1} />
</div>
);
}
}
class B extends React.PureComponent {
render() {
console.log('B is rendering');
return <div>I am update every {this.props.seconds.t} seconds</div>;
}
}
4.使用React.memo来缓存组件
React.memo是一个高阶组件,高阶组件(HOC)是参数为组件,返回值为新组件的函数
React.memo 仅检查 props 变更。如果函数组件被 React.memo 包裹,且其实现中拥有 useState,useReducer 或 useContext 的 Hook,当 state 或 context 发生变化时,它仍会重新渲染。默认情况下其只会对复杂对象做浅层对比,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现
const C = React.memo((props) => {
console.log("C is rending")
return <div>I am update every {props.seconds} seconds</div>
})
5.延迟加载不是立即需要的组件
React.loadable
参考https://blog.csdn.net/my_new_way/article/details/106987751
React-loadable支持React的服务端渲染
React.Lazy/React.Suspense
React.lazy和Suspense并不支持服务端渲染
// App.js
import './App.css';
import React from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
import Loadable from 'react-loadable';
function MyLoadingComponent({ error }) {
if (error) {
return <div>Error!</div>;
} else {
return <div>Loading...</div>;
}
}
// react-loadable
const LoadableComponent = Loadable({
loader: () => import('./pages/home'),
loading: MyLoadingComponent,
});
// React.lazy/React.suspanse
const About = React.lazy(() => import('./pages/about'));
function MyComponent() {
return (
// 显示 <MyLoadingComponent> 组件直至 About 加载完成
<React.Suspense fallback={<MyLoadingComponent />}>
<div>
<About />
</div>
</React.Suspense>
);
}
class App extends React.Component {
render() {
return (
<BrowserRouter>
<Routes>
<Route path='/home' element={<LoadableComponent />} />
<Route path='/about' element={<MyComponent />} />
</Routes>
<div>
<Link to='/home'>Home</Link>
<br />
<Link to='/about'>About</Link>
</div>
</BrowserRouter>
);
}
}
// Home.jsx
import React, { Component } from 'react';
export default class Home extends Component {
render() {
console.log('render home component');
return <div>home</div>;
}
}
import React, { Component } from 'react';
export default class About extends Component {
render() {
console.log('render about component');
return <div>about</div>;
}
}
6.调整CSS而不是强制组件加载和卸载
将不透明度调整为0对浏览器的成本消耗几乎为0(因为它不会导致重排),并且应尽可能优先于更该visibility 和 display
// 避免对大型的组件频繁加载和卸载
function Component(props) {
const [view, setView] = useState('view1');
return view === 'view1' ? <SomeComponent /> : <AnotherComponent />
}
// 使用该方式提升性能和速度
const visibleStyles = { opacity: 1 };
const hiddenStyles = { opacity: 0 };
function Component(props) {
const [view, setView] = useState('view1');
return (
<React.Fragment>
<SomeComponent style={view === 'view1' ? visibleStyles : hiddenStyles}>
<AnotherComponent style={view !== 'view1' ? visibleStyles : hiddenStyles}>
</React.Fragment>
)
}
7.使用React.Fragment避免添加额外的DOM
有些情况下,我们需要在组件中返回多个元素,但是在react规定组件中必须有一个父元素,我们就会在多个元素外套一个div父元素。实际上页面上的元素越多,加载所需的时间就越多。为了减少不必要的加载时间,我们可以使React.Fragment来避免创建不必要的元素。
function Component() {
return (
<React.Fragment>
<h1>Hello world!</h1>
<h1>Hello there!</h1>
<h1>Hello there again!</h1>
</React.Fragment>
)
}