虚拟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上,只触发一次重绘和回流。react

 

 二: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识别列表中全部子组件的最小变化
相关文章
相关标签/搜索