React性能优化(一):一文看懂优化原理及方案 🚀
大家好,我是疯狂的小波,这个系列我们会介绍React性能优化的相关内容,包含为什么要做性能优化、原理、多种实用的解决方案。
当我们开发的项目越来越复杂,或者是对性能要求比较高的时候,就容易遇到性能问题。比较常见的就是当改变某个数据时,视图的更新有延迟或者出现卡顿的情况。那哪些场景下会出现性能问题,我们又应该怎么解决呢?
为什么要做性能优化?
我们来看看一个简单的例子:
function SelectCar() {
const [brand, setBrand] = useState({});
const [count, setCount] = useState(0);
return (
<>
{count}
<button onClick={() => setCount(count + 1)}>修改count</button>
<BrandList brand={brand} />
<Car />
</>
);
}
上述代码中,当点击button 时count 值+1,SelectCar 组件重新渲染;子组件 BrandList、Car 也会重新渲染一次,哪怕此时子组件数据没有任何变化。如果这2个组件内部,还有子组件,也会全部重新渲染。
这种父级组件数据变更,会导致所有子孙组件全部重新渲染。我们可以想象当页面复杂时,会有多大的性能损耗。
除了这种简单的场景,还有很多可能会出现性能问题的原因,接下来我们就从 React的更新渲染机制 来看看可以从哪些方向进行相关的优化。
React的更新渲染机制
想要做好性能优化,我们就需要先了解下 React 的更新渲染机制,了解哪些场景会触发更新,更新内容如何判定,这样才能做到有的放矢,针对性的进行优化。
如上图所示,React 采用的是虚拟DOM (即 VDOM ,React中也叫Fiber)。每次state数据发生变化的时候,React 会检测当前最新的节点和上次渲染的Fiber树之前的差异,然后针对差异的地方进行打标,返回最新的Fiber树,最后将所有差异内容渲染到 真实DOM。这就是整个 更新渲染 的大概过程。
为了获得更优秀的性能,减少更新花费的时间、提高效率。首先映入脑海的便是 减少 diff 的过程,以及减少前后 VDOM 树的差异性,提高 diff 的效率,那么在保证应该更新的节点能够得到更新的前提下,怎么来实现呢?
性能优化方案
减少 diff 的过程我们可以通过 将可变部分与不变部分分离、使用性能优化API 这2种方式优化,减少非必要的重渲染。
减少前后 VDOM 树的差异性,提高 diff 的效率,我们可以根据 React diff算法 的基本原则来进行优化。
也就是如下3个方案:
一、将可变部分与不变部分分离
在 React 中,只要组件的state数据有变更,当前组件及其组件就会重新渲染。而将数据会变动的内容单独拆分到一个独立的组件中,这样就不会影响到父节点和其他的同级节点。
详情查看:《React性能优化(二):将可变部分与不变部分分离 🚀》
二、使用性能优化API
在 React 内部,props 判断是否变更默认是使用的全等比较。而每次父组件重新渲染时,子组件的 props 都是生成的一个新对象,全等判断前后 props 不相等。所以导致父组件每次更新,子组件也会重新渲染。
而使用 React.memo 包裹组件后,会将 props 对象的全等比较,修改为 props 中属性值的比较。 这样我们就能够控制这种非必要的更新了。
详情查看:《React性能优化(三):使用性能优化API 🚀》
三、提高页面渲染效率
当组件数据更新,组件重新渲染时,可以通过减少前后 VDOM 树的差异性,提高 diff 的效率。
基于React 中 diff算法 的3个基本原理,我们可以通过多种方式提高页面渲染的效率。
详情查看:《React性能优化(四):提高页面渲染效率 🚀》
方案落地
在后面的章节中,会分别针对这3种方案进行说明,包括具体的实现方法,代码示例,以及其背后的原理。
通过以上几种方式优化后,我们就能够避免一些非必要的更新,有效减少更新范围,提高更新时的效率,达到最终的性能优化的目的。让我们的界面更新响应速度越快,运行越流畅。
转载自:https://juejin.cn/post/7169558805020311566