Technical dry goods | 7 react performance improvement skills

Time:2022-1-23

Technical dry goods | 7 react performance improvement skills
preface
React is a UI framework developed by the Facebook team. As one of the current three front-end frameworks (the other two are angular and Vue), react provides a data-driven UI development mode and a component-based development method, which can build high-performance front-end applications.
Paile cloud audio and video PAAS cloud platform provides users with console, which provides application management, consumption viewing, expense management, data compass, user management and other functions. The development of console front-end selects react as the basic framework. In the process of using react, we have summarized 7 tips for improving the performance of react, which we share with you here.

Memorize diffing rules

1. When the type of node (including DOM node and component node) changes, react will unload the DOM tree of the node (including child nodes), and then re render the new DOM tree.

2. When the type of DOM node remains unchanged, react will keep the DOM node, and then update the DOM node compared with the attribute changes.
3. When the type of component node remains unchanged, the component instance will remain unchanged. Compare the props attribute and update the component.
4. The above process starts from the root node and recurses to all leaf nodes.
From the above rules, we can see that the component is the protagonist, and the subsequent performance improvement points also focus on the component. It can be seen from the above rules that different components should be used for large changes and attributes should be modified for small changes. If you remember the diffing rule, you can actually write react code with good performance. The above is just a summary. You don’t need to look at the document coordination in detail.

key

When updating, react needs to compare the changes before and after the update to generate a mutation. Without a key, previous components cannot be reused, affecting performance.

Using the array index as the key determines the update and reuse of components based on the index. When the order changes, the change of uncontrolled components will not meet the expectations. For example, it is expected that the position of the first element and the second element will be swapped. Because the array index is used as the key, uncontrolled components are reused (there is a performance improvement skill later, that is, using uncontrolled components), React cannot recognize the location change. Here is an example to illustrate the problem caused by the index as a key.

The best practice is to use a unique value as a key at the list level, such as ID.

Properly split components

We know that react provides component-based development. The basis of writing react code is component splitting. Reasonable component splitting can not only improve the maintainability and reusability of the code, but also improve the performance combined with the following performance skills.

1. An important principle of component splitting is high cohesion and low coupling. The sub component should be an independent unit, the communication information between the sub component and the parent component should be less, and the data request should be placed in the sub component, unless the parent component also needs to use it.

function Page(props) => {

return <Card>
    <MeetingInfo id={props.match.params.id} />
    <UserList />
</Card>;

}
function MeetingInfo(props) {

const { info, setInfo } = useState({});
useEffect(() => {
    getMeeting(props.id).then(res => {
        setInfo(res);
    });
});

return <>
    {
        //Meetinginfo is displayed here
    }
</>;

}
2. Units that can be reused must be extracted into components. The reused components should not depend on the outside, so they only communicate through props. If you want to use context, you can wrap it with a high-level component.
3. The component granularity should not be too fine, which will increase the component level depth and increase the maintenance workload.
4. In order to unify the style, priority should be given to extracting common class names rather than components.

Merge setstate

Merging setstate can reduce the number of render executions, which is a very direct and obvious way to improve performance.
Do not call setstate multiple times in the same code block

//Setstate called more than once
this.setState(state => {

pagination: {
    ...state.pagination,
    current: 1,
}

}, () => {

this.setState({
    loading: true,
});
getData().then(res => {
    // ...
})

});

//Merge setstate
this.setState(state => {

pagination: {
    ...state.pagination,
    current: 1,
},
loading: true,

}, () => {

getData().then(res => {
    // ...
})

});
For simultaneous requests, especially when these requests take about the same time, promise. Com can be used All merge to reduce the number of setstate times
//Before merger
getMeeting().then(info => this.setState({ info }));
getUserList().then(userList => this.setState({ info }));

//After merger
Promise.all([

getMeeting(),
getUserList(),

]).then(([info, userList]) => {

this.setState({
    info,
    userList,
});

});

Avoid complex calculations in render

Ideally, render only displays data, and there will be more or less calculations in actual development. However, complex calculations should be avoided in render, and the values should be calculated and stored in state or props.

//Then the calculation of building tree is done in render
function DeptTree(props) {

return <Tree data={buildTree(props.list)} />

}

//The tree structure data should be calculated and stored in state
function DeptTree(props) {

const { treeData, setTreeData } = useState();
useEffect(() => {
    setTreeData(buildTree(props.list));
}, [ props.list ]);
return <Tree data={treeData} />

}

Using purecomponent

Before updating purecomponent, it will compare whether props and state have changed. If there is no change, render will not be called, so as to improve performance.

import { useState } from ‘react’;
import Child from ‘./Child’;

function Component() {
const [ num, setNum ] = useState(1);
return <div>

<div>
  < button onclick = {() = > setnum (Num + 1)} > Add ({num}) < / button >
</div>
<Child />

</div>;
}

export default Component;
// child.js
import React from ‘react’;

class Child extends React.PureComponent {
render() {

console.log('render')
Return < div > subcomponent < / div >;

}
}

export default Child;
Because purecomponent is used, the render of the sub component will not be called every time num is increased. Purecomponent does shallow comparison, so it uses immutable data.

Use of uncontrolled components

Let’s first look at what is a controlled component, that is, the state of the child component depends on the parent component. This will lead to the need to update the child component. First, we must change the state of the parent component, that is, trigger the render of the parent component. In this case, we should consider whether it can be designed as a non controlled component. In fact, parent-child components are formed. In most cases, they must communicate, In order to avoid forming a controlled relationship, you can use context (usually Redux, which simplifies the use of context) for communication. Common pop-up boxes do not need to be used to control the value displayed by the pop-up box. By placing this in the context, you can open and close the pop-up box without triggering the render of the parent component, which can significantly improve the performance, The following are schematic codes.

//Addsuccess is a fixed function, so this component is an uncontrolled component
<Add onSuccess={this.addSuccess} />
function Add(props) {

return <Modal visible={ props.addVisible }>
    {
        // ...
    }
</Modal>;

}

export default connect(state => ({

addVisible: state[namespace].addVisible,

}))(Add)

summary

The performance improvement skills summarized above, such as merging setstate, using purecomponent and using uncontrolled components, achieve performance optimization by reducing the number of render times, which is also the main performance direction. Of course, merging setstate sacrifices code readability for performance optimization. It is recommended for large projects, and trade-offs can be made for small projects. Finally, the use of uncontrolled components is summarized to reduce the coupling between parent and child components (that is, reasonably splitting components), which not only improves the maintainability of the code, but also improves the performance. I hope reading this article will help you write high-performance react code.