React的diff算法


diff的概念

diff算法, 是 Virtual DOM 产生的一个概念, 用来计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面,从而提高了页面渲染效率。

diff算法出现的背景

调用 React 的 render() 方法,会创建一棵由 React 元素组成的树。在下一次 state 或 props 更新时,相同的 render() 方法会返回一棵不同的树。React 需要基于这两棵树之间的差别来更新 UI。

这个算法问题有一些通用的解决方案,即生成将一棵树转换成另一棵树的最小操作数。 然而,即使在最前沿的算法中,该算法的复杂程度为 O(n 3 ),其中 n 是树中元素的数量。

如果在 React 中使用了该算法,那么展示 1000 个元素所需要执行的计算量将在十亿的量级范围。这个开销实在是太过高昂。
为了降低算法复杂度,react通过一些限制策略,提出了一套O(n) 的启发式算法。

简单的来讲, react 它只比较同一层, 一旦不一样, 就删除. 这样子每一个节点只会比较一次, 所以算法就变成了 O(n).

对于同一层的一组子节点. 他们有可能顺序发生变化, 但是内容没有变化. react 根据 key 值来进行区分, 一旦 key 值相同, 就直接返回之前的组件, 不重新创建.

这也是为什么渲染数组的时候, 没有加 key 值或者出现重复key值会出现一些奇奇怪怪的 bug .

Diff算法的限制策略

  • 只对同级元素进行Diff。如果一个DOM节点在前后两次更新中跨越了层级,那么React不会尝试复用他。
  • 两个不同类型的元素会产生出不同的树。如果元素由div变为p,React会销毁div及其子孙节点,并新建p及其子孙节点。
  • 开发者可以通过 key属性 来暗示哪些子元素在不同的渲染下能保持稳定(即是否可稳定复用)

文章作者: me
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 me !