current position:Home>N methods for optimizing react code
N methods for optimizing react code
2021-08-26 00:41:35 【End in sudden wealth】
Inventory React Code optimized N Methods
Reference resources :
- avoid React Context Duplicate rendering caused by :zhuanlan.zhihu.com/p/50336226
- Immutability in React: There’s nothing wrong with mutating objects: blog.logrocket.com/immutabilit…
- Immutable.js, Persistent data structures and structure sharing - Why use Immutable.js Not the ordinary JavaScript object ?:medium.com/@dtinth/imm…
- Immutable.js How to realize data structure persistence ?: www.cnblogs.com/DM428/p/139…
Catalog
- Use React Its own optimization method :
PureComponent、shouldComponentUpdate、memo、useMemo、useCallback
etc. - React There are several uses that affect performance :
- Misuse context Cause all subcomponents re-render, Whether or not context The consumer ;
- because React By default, the component is based on shallow comparison props To decide whether to update the policy , reference-type props It will make the child component update unnecessarily with the parent component ;
- stay React Component lifecycle methods and React Outside the event callback , Multiple calls
setState
, Lead tosetState
Can't be batched , Cause multiple re renderings
- Immutable data ,
immutable.js
、immer
- Reduce double counting :
reselector
Text
1. Use React Its own optimization method
drive React The sources of component updates are as follows :
- Oneself state Update
- Update of parent component ( No matter props Are there any updates , As long as the parent component is updated , The current component will also be forced to update )
- props to update
forceUpdate
Force update
In a class component , By default shouldComponentUpdate
return true, As long as the above four points happen , Components will be updated . The first three points may lead to unnecessary updates , To avoid unnecessary updates , have access to shouldComponentUpdate
Compare the old and new state And old and new props To determine whether the component should be updated , Easier to use PureComponent
, Its internal shouldComponentUpdate
It's just simple and shallow state and props ( So when state/props When it's the object , If we want to update components , The original value must be overwritten with a new object , Otherwise, the shallow comparison will cause the component to be unable to update ). stay React Similar optimization methods are used in memo
Package components , This can be used in both class components and function components , You can also customize the comparison logic . The above methods are used in the current component to prevent invalid updates , On the parent component, we can also use some methods to prevent invalid updates of the current component , This is mainly through caching props Come on Realization , The method used is useMemo、useCallback
The parcel props Then pass it to the sub components .
2. React There are several uses that affect performance
-
Misuse context May cause all subcomponents re-render, Whether or not context The consumer
Use context The antipattern of :context Subcomponents and context value The updates are placed in a component , Lead to context value update , Let all Consumer component and Non consumer components Indifference update
Use... Correctly context: hold context value The management and consumption components are separated , stay context value When it's updated , Only consumer components will be updated , Do not let non consumer components update
It is also confirmed from the above two examples , If you don't optimize , The child component will be fully updated with the update of the parent component , thus , In addition to context value Management and context Separate consumer components , We can also package consumer components
React.memo()
, To avoid invalid updates to consumer components . -
because React By default, the component is based on shallow comparison props To decide whether to update the policy , reference-type props It will make the child component update unnecessarily with the parent component
In a class component , To prevent this , It should be avoided in
render
Method to create a reference type props And pass it to the subcomponent , Otherwise, every time the parent component re renders , reference-type props Will be a new value , Causes sub components to be re rendered . To avoid the render Create a new reference , For example, don't be in props Pass inline functions in , The callback function should be initialized on the properties of the class component , It's best to use arrow function syntax ( binding this, Look at this article ).And in the function component , It can be used
useMemo、useCallback
The parcel props Then pass it to the sub components , these hooks Will remember the calculated value , The result of the last calculation can be used every time the component is rendered , Of course, if the result of the calculation is an object , Its reference will not change , Therefore, it will not cause sub components to re render . -
stay React Component lifecycle methods and React Outside the event callback , Multiple calls
setState
, Lead tosetState
Can't be batched , Cause multiple re renderingsWe know setState It could be asynchronous , This asynchrony does not mean setState It's asynchronous , But rather setState The effect is asynchronous , That is to say state The update of is asynchronous ,React Of setState In the same batch transaction, it will be merged into one update , This improves React Performance of . The following situations will setState Batch into one :
- Multiple setState In the same React Execute... In the composite event callback
- Multiple setState In the same React Execute in life cycle
export default function App() { const [a, setA] = useState(0); const [b, setB] = useState(0); const [c, setC] = useState(0); const handleClick = () => { setA((a) => a + 1); setB((b) => b + 2); setC((c) => c + 3); }; console.log("render"); return ( <div className="App"> <h1>Hello CodeSandbox</h1> <button onClick={handleClick}>click</button> <h2> {a}-{b}-{c} </h2> </div> ); } Copy code
But sometimes setState The effect may also occur synchronously , If setState Not really React Call in composite event , For example, call... Multiple times in the following cases setState, that state Your updates are synchronized , Can't be batched , Components change with each time setState to update :
- DOM Native event callback
- Asynchronous callback , promise.then() 、setTimeout
export default function App() { const [a, setA] = useState(0); const [b, setB] = useState(0); const [c, setC] = useState(0); const handleClick = () => { setTimeout(() => { setA((a) => a + 1); setB((b) => b + 2); setC((c) => c + 3); }, 0); /* Promise.resolve().then(() => { setA((a) => a + 1); setB((b) => b + 2); setC((c) => c + 3); }); */ }; console.log("render"); return ( <div className="App"> <h1>Hello CodeSandbox</h1> <button onClick={handleClick}>click</button> <h2> {a}-{b}-{c} </h2> </div> ); } Copy code
In this case , We can change state Structure , Will be multiple state Synthesize once , And minimize setState The number of times
React 18 after , All items will be batched by default setState, Whether it's React Composite event callback inside , still setTimeout Wait for asynchronous callback . But there are some cases , If we still need to prohibit mass production ,React There is also a API
ReactDOM.fluchSyc(() ⇒ {setState...})
You can skip batch processing
3. Immutable data
Immutable data is , When you try to change the value of a variable , He will create a new variable instead of the original variable , Instead of directly modifying the original variable , The original variable value is immutable .
Immutable data is part of functional programming
This for React Especially important . React We are not allowed to modify state There is a reason , Of course, this is also caused by its own design , Do not directly modify state It can make React By comparing the old and the new state To decide whether to update components , If state Is a deeply nested object , Only deep recursive comparison , This will consume the performance of the application , It also brings inconvenience to developers . If only shallow comparison is allowed ( use ===
、!==
Operator ) It will be more efficient to know whether the component should be updated . So we are React Update in the component state That's what I wrote when I was :
state = {
user: {
name: 'chege',
age: 24,
friend: {
name: 'xiaoming',
age: 22
}
}
}
addAge() {
// spread operator ...
this.setState({
user: {
...this.state.user,
age: 25
}
})
/* perhaps Object.assign this.setState( Object.assign({}, this.state.user, {age: 25}) ) */
}
Copy code
...
and Object.assign()
Meeting Shallow copy object , Old and new objects will only reference different objects at the first level , References to deep objects remain the same . This ensures that components that depend on shallow objects can be updated efficiently at the same time , It also avoids unnecessary updates to components that rely on deep objects , Because we just changed the shallow objects , The deep object has not changed .
stay Redux in ,reducer It also requires a pure function , Do not modify state, The reason is the same as React equally , For easier judgment state Whether to update :
Do not modify state. Use Object.assign()
Create a new copy . You can't use Object.assign(state, { visibilityFilter: action.filter })
, Because it changes the value of the first parameter . You have to set the first parameter to an empty object . You can also turn on ES7 Proposal object expansion operator support , To use { ...state, ...newState }
To achieve the same purpose .
But if state The object is a little deeper , We may have to write a lot ...
and Object.assign()
, This will cause the code to look bad :
state = {
user: {
name: 'chege',
age: 24,
friend: {
name: 'xiaoming',
age: 22
}
}
}
addFriendAge() {
// spread operator ...
this.setState({
user: {
...this.state.user,
friend: {
...this.state.user.friend,
age: 23
}
}
})
/* perhaps Object.assign this.setState( Object.assign( {}, Object.assign( {}, this.state.user, ), {age: 25} ) ) */
}
Copy code
If you want to balance code aesthetics and application performance , We can use some third-party libraries , They create a kind of Persistent data structures , When creating immutable objects , Ability to reuse old object parts that do not need to be changed , Save time and space for creating objects .
Look at the light copy above ...
and Object.assign()
, Although we have achieved what makes us React The application is running normally , And achieve the purpose of optimization to a certain extent , But it's not the best way , Besides the ugly code , Also, shallow copies still consume some performance , When the copied object contains 100000 When there are two attributes ,JavaScript Have to copy every attribute honestly , If the attribute is a basic type , A copy of the value of the basic type . So shallow copy will still waste memory and program running time . One can be used not only for React The optimized data immutability implementation scheme is Persistent data structures (Persistent data structures), Its purpose is to create an immutable data , Each change will return a new version , Instead of directly modifying the original data , At the same time, in order to save memory and modification time , Reuse unchanged parts , This is it. Structure of Shared (structural sharing).
There are many realizations Persistent data structures and Structure of Shared The plan , There is no expansion here , Just talk about js Methods used in several libraries that implement immutable data :
-
Immutable.js
: Its persistent data structure is based on Prefix tree (trie, Also called dictionary tree ), At the node of the tree 0 and 1 To the left 、 Right node , The path connected from top to bottom nodes path It means key , Leaf nodes represent key values , Immutability is achieved through the copy path , For example, you want to change a leaf node (path by 101, The value is 12), Just copy the nodes on that path , The next node shares . Each modification will produce a new path like the one on the right , But the structure of the tree has not changed , The new path and the original unchanged node can also form a new tree , And the structure is the same , Realize the sharing of unmodified parts . This is the general principle . Some more details are , Handle key hash Numerical value , The value is converted to binary , Mapping to key values through bit partitions as keys , More details can be found here : -
immer.js
: Did not implement its own data persistence structure , Only byproxy
To hijack data modification , Two copies of data before and after modification are maintained internally , The data structure used is also js The original object of , When there is a large amount of data, it will consume a lot of performance .immer.js
The advantages of api Less , Easy to use .
Use these libraries , We can modify the data directly , When it returns, it is a new data , The original data will not be modified , At the same time, the first and second data will only break the reference in the modified part , The unmodified part will share the reference .
use immer.js
modify state, Simple and clear :
import produce from "immer"
state = {
user: {
name: 'chege',
age: 24,
friend: {
name: 'xiaoming',
age: 22
}
}
}
addFriendAge() {
this.setState(produce(draft => {
draft.user.firend.age= 23
}))
}
Copy code
We can test and use immer.js
Can you share the unchanged part :
import produce from "immer";
const state = {
user: {
name: "chege",
age: 24,
friend1: {
name: "xiaoming",
age: 22
},
friend2: {
name: "xiaoming",
age: 22
}
}
};
const nextState = produce(state, (draftState) => {
draftState.user.friend1.age = 23;
});
console.log(nextState.user === state.user); // false,user Belong to the changed path A node of
console.log(nextState.user.friend1 === state.user.friend1); // false, friend1 Belong to the changed path A node of
console.log(nextState.user.friend2 === state.user.friend2);
// true, Shared objects for change ,friend2 Does not belong to the changed path A node of , Is the part that should be shared
Copy code
4. Reduce double counting
Redux Medium state All on a tree , When a component subscribes to a state When , You need to deconstruct from the top store, From the top to the next level, and finally to the target state, There may also be some calculations to generate derived data , Used eventually in UI Come out of reality . When store When it's updated , All subscribed state All components will receive update notifications , Recalculate respective subscription data , Even if the subscribed part is not updated , Or updated, the final calculation result was the same at that time , Will be recalculated :
In the following example , When we click add a when ,ConnectChildA
and ConnectChildB
Of mapStateToProps
It will be carried out , Even though ConnectChildB
Subscribe to the state No updates , But they all depend on one store, So they all received update notifications , All depend on store All components have been fully updated .
because redux The design of the ,store Any next state All the following components will be fully updated , This is inevitable , However, it can avoid too many invalid calculations during update . stay mapStateToProps This node caches the calculation results , Avoid unnecessary updates to components .reselector Please refer to :
copyright notice
author[End in sudden wealth],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210826004127138b.html
The sidebar is recommended
- Crazy blessing! Tencent boss's "million JVM learning notes", real topic of Huawei Java interview 2020-2021
- JS JavaScript how to get the subscript of a value in the array
- How to implement injection in vuex source code?
- JQuery operation select (value, setting, selected)
- One line of code teaches you how to advertise on Tanabata Valentine's Day - Animation 3D photo album (music + text) HTML + CSS + JavaScript
- An article disassembles the pyramid architecture behind the gamefi outbreak
- BEM - a front-end CSS naming methodology
- [vue3] encapsulate custom global plug-ins
- Error using swiper plug-in in Vue
- Another ruthless character fell by 40000, which was "more beautiful" than Passat and maiteng, and didn't lose BMW
guess what you like
-
Huang Lei basks in Zhang Yixing's album, and the relationship between teachers and apprentices is no less than that in the past. Netizens envy Huang Lei
-
He was cheated by Wang Xiaofei and Li Chengxuan successively. Is an Yixuan a blessed daughter and not a blessed home?
-
Zhou Shen sang the theme song of the film "summer friends and sunny days" in mainland China. Netizen: endless aftertaste
-
Pink is Wangyuan online! Back to the peak! The new hairstyle is creamy and sassy
-
Front end interview daily 3 + 1 - day 858
-
Spring Webflux tutorial: how to build reactive web applications
-
[golang] walk into go language lesson 24 TCP high-level operation
-
August 23, 2021 Daily: less than three years after its establishment, Google dissolved the health department
-
The female doctor of Southeast University is no less beautiful than the female star. She has been married four times, and her personal experience has been controversial
-
There are many potential safety hazards in Chinese restaurant. The top of the program recording shed collapses, and the artist will fall down if he is careless
Random recommended
- Anti Mafia storm: He Yun's helpless son, Sun Xing, is destined to be caught by his dry son
- Introduction to flex flexible layout in CSS -- learning notes
- CSS learning notes - Flex layout (Ruan Yifeng tutorial summary)
- Today, let's talk about the arrow function of ES6
- Some thoughts on small program development
- Talk about mobile terminal adaptation
- Unwilling to cooperate with Wang Yibo again, Zhao Liying's fans went on a collective strike and made a public apology in less than a day
- JS function scope, closure, let, const
- Zheng Shuang's 30th birthday is deserted. Chen Jia has been sending blessings for ten years. Is it really just forgetting to make friends?
- Unveil the mystery of ascension
- Asynchronous solution async await
- Analysis and expansion of Vue infinite scroll source code
- Compression webpack plugin first screen loading optimization
- Specific usage of vue3 video play plug-in
- "The story of huiyeji" -- people are always greedy, and fairies should be spotless!
- Installing Vue devtool for chrome and Firefox
- Basic usage of JS object
- 1. JavaScript variable promotion mechanism
- Two easy-to-use animation JS that make the page move
- Front end Engineering - scaffold
- Java SQL Server intelligent fixed asset management, back end + front end + mobile end
- Mediator pattern of JavaScript Design Pattern
- Array de duplication problem solution - Nan recognition problem
- New choice for app development: building mobile applications using Vue native
- New gs8 Chengdu auto show announces interior Toyota technology blessing
- Vieira officially terminated his contract and left the team. The national security club sent blessings to him
- Less than 200000 to buy a Ford RV? 2.0T gasoline / diesel power, horizontal bed / longitudinal bed layout can be selected
- How does "heart 4" come to an end? Pinhole was boycotted by the brand, Ma Dong deleted the bad comments, and no one blessed him
- We are fearless in epidemic prevention and control -- pay tribute to the front-line workers of epidemic prevention!
- Front end, netty framework tutorial
- Xiaomi 11 | miui12.5 | android11 solves the problem that the httpcanary certificate cannot be installed
- The wireless charging of SAIC Roewe rx5 plus is so easy to use!
- Upload and preview pictures with JavaScript, and summarize the most complete mybatis core configuration file
- [25] typescript
- CSS transform Complete Guide (Second Edition) flight.archives 007
- Ajax foundation - HTTP foundation of interview essential knowledge
- Cloud lesson | explain in detail how Huawei cloud exclusive load balancing charges
- Decorator pattern of JavaScript Design Pattern
- [JS] 10. Closure application (loop processing)
- Left hand IRR, right hand NPV, master the password of getting rich