美文网首页
React-diff

React-diff

作者: 太_2_真_人 | 来源:发表于2020-05-08 00:05 被阅读0次

React是根据Virtual DOM的对比来更新DOM的。这种用来对比的方法被称为diff算法,该算法由fb进一步的优化,使得React的渲染性能得到进一步提升。

1. 传统diff

传统diff算法通过循环递归对节点进行依次对比,效率低下,使得算法复杂度为O(n^3),如果节点数过于庞大,即使cpu的计算速度达到30亿次/s,也很难在1s内计算出结果。

​ 1)Tree edit distance(树的编辑距离)

从左图修改成右图

image
  • 删除ul节点

  • 添加p节点

  • 添加text

在递归过程中依次将当前节点拆分成子树,然后依次计算每个子树的edit distance,所以上图的树的最小编辑距离为3

​ 2)Tree edit distance算法演进

image
2. React的diff

diff算法的复杂度取决于策略,React采用的三大策略将diff复杂度由O(n^3)转化为O(n),效果提升如图:

image

三大策略分别为:

  • tree diff

    • React对树的算法进行了简洁的优化,由于DOM节点操作涉及到跨层级的移动操作少到可以忽略不计,所以React只对树进行分层比较。当发现节点已经不存在时,会删除该节点及所有子节点,不回再做多余的遍历比较,只需要对树进行依次比较即可。
    image
    • 如果涉及到了DOM的跨层级操作,React只会执行添加和删除2个操作,先添加一个新节点,然后添加子节点,再删除旧节点。如下图,执行步骤为: create A => create B => create C => delete A

      image

      A节点会被重新创建而不是移动,所以React官方建议不要进行DOM节点的跨层级操作,可以通过css属性的隐藏、显示对节点操作,而不是真正的删除、插入节点。

  • component diff

    React是基于组件构建应用的,对组件的diff也非常简洁

    • 同一类型组件,按照原策略进行Visual DOM对比
    • 同一类型组件,Visual DOM没发生任何变化,React提供一个shouldComponentUpdate api供用户手动选择是否需要进行diff比较,如果使用了forceUpdate则强制比较,shouldComponentUpdate失效。
    • 不同类型组件,将原有组件标记为dirty component,删除旧组件重新添加新组件。
  • element diff

    当节点处于同一层时,diff提供了3种节点操作

    • INSERT_MARKUP

      • 组件C不在集合(AB)中,需要插入操作
    • REMOVE_NODE

      • 组件C在集合(ABC)中,集合需要变成新集合(AB),则需要删除C

      • 组件C在集合(ABC)中,但C改变了,不能复用和移动,需要删除C在新建C

    • MOVE_EXISTING

      • 组件C在集合(ABC)中,集合更新时需要将C和A的位置调换,传统diff需要将C移动到A的位置,并将C和旧A进行diff,再添加C,React diff只需要将C移动到A位置,并添加一个唯一的key进行区分,直接移动即可。
总结
  • React diff对传统diff进行优化,使得算法复杂度成几何倍减小

  • 尽量减少对DOM跨层级的操作,尤其是将列表最后一项移动到列首

  • 对于同一层级的一组子节点,通过设置唯一key来进行区分

  • 开发组件时,保持稳定的DOM结构有助于性能的提升

  • 懂得借助react diff去解决实际开发中的一系列问题

参考

https://www.jianshu.com/p/3ba0822018cf

https://www.jianshu.com/p/8e5aee42be35

https://segmentfault.com/a/1190000018914249#item-4-5

https://www.zhihu.com/question/66851503

相关文章

  • React-diff

    React是根据Virtual DOM的对比来更新DOM的。这种用来对比的方法被称为diff算法,该算法由fb进一...

  • React-Diff算法

    Diff算法 React.js 相对于直接操作原生DOM有很大的性能优势,很大程度上都要归功于virtual DO...

  • react-diff算法详解

    前言 本文是我阅读《深入React技术栈》所写的总结笔记。如果您觉得本站的markdown代码高亮不友好,建议您查...

  • react进阶-节点比较

    1.key增加性能,需要注意: 2.关于key的使用 3.diff算法 react-diff算法就是上面说的启发式...

网友评论

      本文标题:React-diff

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