纵横研究院React技术专题社区

React中的diff算法

2019-06-03  本文已影响32人  月半君o

diff作为Virtual DOM的加速器,其算法上的改进优化是React整个界面渲染的基础和性能保障。传统的diff算法,计算一棵树形结构转换成另一颗树形结构的最少操作是通过循环递归对节点进行依次对比,这种方式效率低下,算法复杂度达到O(n^3),其中n是树中节点的总数。而React diff将O(n^3)复杂度的问题转换成O(n)复杂度的问题。

  1. diff策略

基于以上策略,React分别对tree diff、component diff以及element diff进行算法优化。

1.1 tree diff

基于策略一,React的做法是把dom tree分层级,对于两个dom tree只比较同一层次的节点,忽略Dom中节点跨层级移动操作,只对同一个父节点下的所有的子节点进行比较。如果对比发现该父节点不存在则直接删除该节点下所有子节点,不会做进一步比较,这样只需要对dom tree进行一次遍历就完成了两个tree的比较。

DOM层级变换
两个tree进行对比,右边的新tree发现A节点已经没有了,则会直接销毁A以及下面的子节点B、C;在D节点上面发现多了一个A节点,则会重新创建一个新的A节点以及相应的子节点。
具体的操作顺序:create A → create B → creact C → delete A。
由此可发现,当出现节点跨层级移动时,并不会出现想象中的移动操作,而是以A为根节点的整个树被重新创建。这是一种影响React性能的操作,因此官方不建议进行DOM节点跨层级的操作。
1.2 component diff

React应用是基于组件构建的,对于组件的比较优化侧重于以下几点:

1.3 element diff

对于同一层级的element节点,diff提供了以下3种节点操作:

优化后diff的不足
image.png

按照上述顺序优化,则旧集合中D的位置是最大的,最少的操作只是将D移动到第一位就可以了,实际上diff操作会移动D之前的三个节点到对应的位置,这种情况会影响渲染的性能。

优化建议

在开发过程中,同层级的节点添加唯一key值可以极大提升性能,尽量减少将最后一个节点移动到列表首部的操作,当节点达到一定的数量以后或者操作过于频繁,在一定程度上会影响React的渲染性能。比如大量节点拖拽排序的问题。

上一篇 下一篇

猜你喜欢

热点阅读