美文网首页
react diff

react diff

作者: 麦子_FE | 来源:发表于2017-12-12 17:58 被阅读46次

    diff策略

    1.web UI中DOM节点跨层级的移动操作特别少,可以忽略不计。

    2.拥有相同类型的两个组件将会生成相似的树形结构,拥有不同类型的两个组件将会生成不同树形结构。

    3.对于同一层级的一组自节点,他们可以通过唯一id进行区分。

    基于以上策略,react分别对一下进行算法优化。

    tree diff

    react对树的算法进行了分层比较。react 通过 updateDepth对Virtual Dom树进行层级控制,只会对相同颜色框内的节点进行比较,即同一个父节点下的所有自节点。当发现节点不存在,则该节点和其子节点都会被删除。酱紫是需要遍历一次dom树,就完成了整个dom树的对比。

    分层比较

    如果是跨层级的移动操作,如图

    跨层级操作

    当根结点发现A消失了,会删除掉A以及他的子节点。当发现D上多了一个A节点,会创建A(包括自己点)节点作为子节点。

    所以:当进行跨层级的移动操作,react并不是简单的进行移动,而是进行了删除和创建的操作,会影响到react性能。所以要尽量避免跨层级的操作。(例如:控制display来达到显示和隐藏,而不是真的添加和删除dom)

    component diff

    1如果是同类型的组件,则直接对比virtual Dom tree

    2.如果不是同类型的组件,会直接替换掉组件下的所有子组件

    3.如果类型相同,但是可能virtual DOM 没有变化,这种情况下我们可以使用shouldComponentUpdate()  俩判断是否需要进行diff

    如图:

    如果组件D和组件G,如果类型不同,但是结构类似。这种情况下,因为类型不同,所以react会删除D,创建G。所以我们可以使用shouldComponentUpdate()返回false不进行diff。

    所以:component diff 主要是使用shouldComponentUpdate() 来进行优化。

    element diff

    element diff 涉及三种操作:插入,移动,删除。

    不使用key的情况

    不使用key的话,react对新老集合对比,发现新集合中B不等于老集合中的A,于是删除了A,创建了B,依此类推直到删除了老集合中的D,创建了C于新集合。= 

    酱紫会产生渲染性能瓶颈,于是react允许添加key进行区分

    使用key的情况

    react首先对新集合进行遍历,for( name in nextChildren),通过唯一key来判断老集合中是否存在相同的节点,如果没有的话创建,如果有的话,if (preChild === nextChild ) 进行移动操作。

    移动优化:

    在移动前,会将节点在新集合中的位置和在老集合中lastIndex进行比较,如果

    if (child._mountIndex < lastIndex) 进行移动操作,否则不进行移动操作。这是一种顺序移动优化。只有在新集合的位置 小于 在老集合中的位置  才进行移动。

    如果遍历的过程中,发现在新集合中没有,但是在老集合中的节点,会进行删除操作。

    所以:element diff 通过唯一key 进行diff 优化。

    总结:

    1.react中尽量减少跨层级的操作。

    2.可以使用shouldComponentUpdate() 来避免react重复渲染。

    3.添加唯一key,减少不必要的重渲染。

    相关文章

      网友评论

          本文标题:react diff

          本文链接:https://www.haomeiwen.com/subject/aamgixtx.html