最通俗的React 15的diff算法和虚拟dom

474 阅读3分钟

本文是在本人想学习React Fiber时发现先要了解React diff算法才写下的,以下内容如果有问题希望大家评论指出,一起进步。

前言

React 的 Diff算法和Virtual DOM(虚拟DOM)是在React 15中就已经存在的东西,他们是React中一个重要的概念,最初是由Facebook的工程师提出的,用于提高React在渲染时的性能。

什么是Virtual DOM

先了解DOM: DOM就是浏览器根据HTML转换出来的结构,一方面表现出HTML的内容与架构,另一方面让开发者有机会使用javeScript通过DOM去操作页面。

Virtual DOM:中文翻译虚拟DOM,他不是一个真正的DOM,DOM是由浏览器产生的,但Virtual DOM是JS的产物,存在于内存(memory)中。

存在意义: 为了避免每次DOM操作都去触发浏览器的重绘和回流,框架会先将原来的DOM复制出来,当 state 或 props 改变时,会触发React.creatElement()建立一个新的Virtual DOM,然后计算出新旧Virtual DOM中的区别,对改变的地方进行更新。当更新完成后,React会将新的虚拟DOM渲染到浏览器的缓存中,在某一帧中,将缓存的内容批量执行,从而将虚拟DOM更新到真实DOM上。而且只会操作有改变的地方,避免多次触发重绘和回流。

这里面计算新旧区别的就是Diff算法

Diff算法

为了降低算法的复杂度,react会有三个规则限制

1、只对同级元素进行diff,如果一个DOM节点在前后出现在不一样的层级,那么React不会复用。 image.png

2、React会对类型进行比较,如果元素由div变成p,那么React会销毁div及其子节点,重新创建。

3、上面单一节点的比较,之后是多个子节点的情况

  • 如果子节点数量不同,直接重新渲染整个子树。
  • 如果子节点数量相同,React会为每个新节点在旧节点中查找对应位置的节点,然后递归比较子节点,更新有变化的部分。
  • 在比较子节点时,React会使用key属性进行优化。如果发现旧树中某个节点的key在新树中也存在,就会将该节点在新树中的位置调整到对应的位置,从而避免了不必要的节点重新渲染。

React会对Key属性进行比较,举个🌰

..更新前
<div>
    <div key="a">111</div>
    <p key="b">2222</p>
</div>
<div>
    <p key="b">2222</p>
    <div key="a">111</div>
</div>

上面的diff只会交换顺序复用之前的节点,而不会销毁。具体图如下

image.png

总结

React 的 Virtual DOM 和 Diff 算法是 React 实现高效渲染的核心。

Virtual DOM 是指在 JavaScript 中使用对象描述真实 DOM 的结构,并通过 React 提供的 diff 算法进行高效比对、计算出差异,最终只对需要更新的部分进行渲染,从而提高页面渲染效率。

React 的 diff 算法会比较两个虚拟 DOM 的结构,并通过 Diff 算法进行计算出哪些部分需要更新,从而避免全量更新整个页面,只更新部分需要更新的节点。

React 的 Diff 算法主要分为两个阶段,分别是 Diff 策略的确定和 Diff 的执行。

在 Diff 策略的确定阶段,React 会通过简单地比较两个虚拟 DOM 树的结构,尽可能快地确定哪些节点需要更新,哪些节点需要删除,哪些节点需要添加。

在 Diff 的执行阶段,React 会根据前面确定的策略,执行具体的 DOM 操作,例如对需要更新的节点进行更新、对需要添加的节点进行插入、对需要删除的节点进行删除等。

总的来说,React 的 Virtual DOM 和 Diff 算法极大地提高了 React 应用的性能,让我们可以更高效地构建用户界面。