React系列笔记之二
了解React的核心概念对于React的学习至关重要,这一篇详细介绍虚拟DOM和Diff算法。
虚拟DOM(Virtual Document Object Model)
Dom的本质: 浏览器中的概念,用JS对象表示页面上的元素,并提供了操作DOM对象的API
React中的虚拟DOM: 是框架中的概念,是程序员用JS对象来模拟页面上的DOM和DOM嵌套,目的是实现页面中DOM元素的高效更新。
虚拟DOM的原理:
- 利用Javascript对象模拟DOM树并且渲染DOM树
- 通过Diff算法比较新旧DOM树,得到差异的对象
- 将差异的对象应用到渲染的DOM树中
DOM vs 虚拟DOM:
- 虚拟DOM不会进行排版或重绘操作
- 虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分,最后是在真是DOM中进行排版和重绘,减少过多DOM节点排版和重绘损耗
- 真实DOM频繁排版与重绘的效率很低
- 虚拟DOM有效降低大面积的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部
虚拟DOM总损耗 = 虚拟DOM增删改 + (与Diff算法效率有关)真实DOM差异增删改 + (较少节点)排版和重绘
真实DOM总损耗 = 真实DOM完全增删改 + (可能较多的节点)排版与重绘
Diff算法
Diff算法实际上就是一个调和的具体实现,作用是计算出Virtual DOM中真正变化的部分,并且只针对该部分进行原生的DOM操作,而非重新渲染整个页面。
- Tree Diff :新旧DOM树逐层对比,对树的每一层进行遍历
- Component Diff : 数据层面的差异比较——在进行Tree时,每层组件级别的对比
- 如果都是同一个类型的组件(即两个节点是同意组建类别的两个不同的实例),按照原策略继续比较Virtual DOM即可
- 如果出现不同类型的组件,则改组件判断为dirty component,从而替换整个组件下的所有子节点
- Element Diff :结构差异的比较——组件对比时,如两组件类型相同,则进行元素级别对比
首先进行第一层的比较,第一层都是R,不发生变化;
然后进入第二层Component Diff,发现A组件没有,则删除A及其子组件B,C;
最后比较第三层,创建A及其子组件B,C
当节点处于同一层级时,Diff提供三种DOM操作:删除、移动、插入。