虚拟DOM与DIFF算法

Posted fang-1207

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚拟DOM与DIFF算法相关的知识,希望对你有一定的参考价值。

前言:虚拟DOM(Virtual dom),也就是我们常说的虚拟节点,它是通过JS的Object对象模拟DOM中的节点,然后再通过特定的render方法将其渲染成真实的DOM的节点。

例子:

// 创建虚拟节点
var temp = document.createDocumentFragment();

for( var i=0; i<100; i++ ){
    var li = document.createElement(‘li‘);
    // 将li放入虚拟节点中,这一步操作不会产生重绘回流
    temp.appendChild(li);
    li.innerhtml = i;
}

// 真实节点的操作
ul1.appendChild(temp);

 

一:react 的虚拟dom是怎么实现的

首先说说为什么要使用Virturl DOM,因为操作真实DOM的耗费的性能代价太高,所以react内部使用js实现了一套dom结构,
在每次操作在和真实dom之前,使用实现好的diff算法,对虚拟dom进行比较,递归找出有变化的dom节点,然后对其进行更新操作。
为了实现虚拟DOM,我们需要把每一种节点类型抽象成对象,每一种节点类型有自己的属性,也就是prop,每次进行diff的时候,react会先比较该节点类型,
假如节点类型不一样,那么react会直接删除该节点,然后直接创建新的节点插入到其中,假如节点类型一样,那么会比较prop是否有更新,假如有prop不一样,
那么react会判定该节点有更新,那么重渲染该节点,然后在对其子节点进行比较,一层一层往下,直到没有子节点

 

二:为什么要使用虚拟节点?

频繁的操作DOM,会大量的造成页面的重绘和回流,出于性能优化的考虑,我们应该减少重绘和回流的操作。

重绘:例如 div1.style.color=‘red‘ 这种代码,只能改变颜色,并不会影响其他元素的布局,这种操作被称为重绘。

回流:例如 div1.style.padding = ‘20px‘ 这种代码,会影响到其他元素的布局,这种操作被称为回流。

回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流。

对虚拟节点的DOM操作,并不会触发重绘和回流,把处理后的虚拟节点映射到真实DOM上,只触发一次重绘和回流。

 

 二:diff算法

DIFF算法是DOM更新的一种算法,指页面被更新时,程序用哪种策略去做更新DOM

把树形结构按照层级分解,只比较同级元素。
给列表结构的每个单元添加唯一的key属性,方便比较。
React 只会匹配相同 class 的 component(这里面的class指的是组件的名字)
合并操作,调用 component 的 setState 方法的时候, React 将其标记为 - dirty.到每一个事件循环结束, React 检查所有标记 dirty的 component重新绘制.
选择性子树渲染。开发人员可以重写shouldComponentUpdate提高diff的性能
#

三:react性能优化方案

重写shouldComponentUpdate来避免不必要的dom操作
使用 production 版本的react.js
使用key来帮助React识别列表中所有子组件的最小变化

 

 

 

 

以上是关于虚拟DOM与DIFF算法的主要内容,如果未能解决你的问题,请参考以下文章

React 虚拟dom与diff算法

分析diff算法与虚拟dom(理解现代前端框架)

vue虚拟dom原理

虚拟DOM与DIFF算法

React的虚拟DOM与diff算法的理解

Snabbdom:虚拟DOM和Diff算法