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