React学习: React性能优化
React性能优化,你需要知道的一切
Q&A
- 为什么 React需要性能优化API
- 因为默认情况,
react-tree
中的一个组件更新,会触发root.render
来渲染整个组件更新 - 为了让上面的更新更加的效率,有时候,我们需要显式的让 React 知道哪些是没有变化的,从而直接跳过Diff,更新环节
- 即使更新整棵 tree,没有变化的也是直接跳过,所以,性能也没有什么大问题
- 因为默认情况,
- React性能优化应该遵循的原则
- 将
变的部分
与不变的部分
分离 - 变的部分:
- props
- state
- context
- 3部分都是由 state 衍生出来的
- 将
- 原理
- 因为如果 state/props/context 不变,VIEW就不应该发生变化;
- 不变,性能就是最好的。
- 性能优化的本质:让不应该变化的 state 保持不变,并让 React 知道
场景1
平级组件之间存在:变化 与不变 的场景,直接分离变化,让 Entry 组件为没有任何 state/props/context 的组件
- 优化前
- 优化后
- 这个是不使用性能优化API的例子
import { useState } from 'react';
export default () => {
const [num, setNum] = useState(0);
return (
<div>
<input type="number" value={num} onChange={(e) => setNum(+e.target.value)} />
<p>Number is:{num}</p>
<ExpensiveCon />
</div>
);
};
function ExpensiveCon() {
let now = performance.now();
while (performance.now() - now < 100) {}
console.log('expensive render...');
return <p>耗时的组件....</p>;
}
import { useState } from 'react';
export default () => {
return (
<div>
<Input />
<ExpensiveCon />
</div>
);
};
function Input() {
const [num, setNum] = useState(0);
return (
<>
<input type="number" value={num} onChange={(e) => setNum(+e.target.value)} />
<p>Number is:{num}</p>
</>
);
}
function ExpensiveCon() {
let now = performance.now();
while (performance.now() - now < 100) {}
console.log('expensive render...');
return <p>耗时的组件....</p>;
}
变化的部分
function Input() {
const [num, setNum] = useState(0);
return (
<>
<input type="number" value={num} onChange={(e) => setNum(+e.target.value)} />
<p>Number is:{num}</p>
</>
);
}
场景2
父子组件(容器)之间存在:变化 与不变 的场景,直接分离变化,让 Entry 组件为没有任何 state/props/context 的组件
- 优化前
- 优化后
- 不使用性能优化,将children 不变抽离
import { useState } from 'react';
export default () => {
const [num, setNum] = useState(0);
return (
<div data-num={num}>
<input type="number" value={num} onChange={(e) => setNum(+e.target.value)} />
<p>Number is:{num}</p>
<ExpensiveCon />
</div>
);
};
function ExpensiveCon() {
let now = performance.now();
while (performance.now() - now < 100) {}
console.log('expensive render...');
return <p>耗时的组件....</p>;
}
import React, { useState } from 'react';
export default () => {
return (
<InputWrapper>
<ExpensiveCon />
</InputWrapper>
);
};
function InputWrapper({ children }: { children: React.ReactNode }) {
const [num, setNum] = useState(0);
return (
<div data-num={num}>
<input type="number" value={num} onChange={(e) => setNum(+e.target.value)} />
<p>Number is:{num}</p>
{children}
</div>
);
}
function ExpensiveCon() {
let now = performance.now();
while (performance.now() - now < 100) {}
console.log('expensive render...');
return <p>耗时的组件....</p>;
}
如何判断 state/props/context
不变呢?
为什么需要性能优化
API
,因为有时候会出现children
为{}
造成重复渲染的情况。
- 如何比较:全等,比较高效,但不易命中
- 浅对比:低效,易命中
ps: React 组件的 children
,即使没有值,也会有 {}
这个产生
总结,为什么需要性能优化
- React 的子组件变化会导致整体重新渲染
- 但如果优化得当,很多不变的节点,可以直接跳过渲染
- 最终每次重新渲染的情况,只会渲染变化的
- 保证 React 性能非常的 ok