为什么会写出这篇文章呢?
可能的原因是以前学习框架的时候只学语法和原理不明白,被问到使用框架有什么好处也回答不上来,正是因为这种情况,所以今天要来探讨一下Virtual DOM的作用原理。
在了解Virtual DOM之前什么是DOM吧!
DOM是什么?
文件模型(Document Object Model,DOM) HTML、XML 和 SVG 文件的程序介面。它提供了文件(树)的程序的文件表示方法,并定义了访问并改变文件架构、风格和内容的方法。(摘取自MDN的部分说明)
由下图可以知道DOM是树状结构从文档根结点向下延伸,下面依附了很多节点
引用MDN的图纸
我们经常利用js来操作DOM更新浏览器在更新触发画面的重新声明,当回流时间以及回流(重)这两个更新机制。
重绘
画面元素更换样式的时候就触发(background-color、color…)
回流
更改画面的操作结构(结构排列)触发(更改视窗大小,css属性:position、width、height…)
很简单,这是一个很正常的运行原因,它是一个非常重要的播放器就可以只更新需要异动的部分。
Virtual DOM的流程
1、什么东西使用setState()方法的时候,React 会先复制一个dom(即为Virtual DOM )
2、的改变时,会比对先前的虚拟 DOM 和当前的虚拟 DOM 区别,当重新行动组件的不同状态
3、Virtual DOM 先用的演算法(diff算出实际的部分,比对之后的不同,再动真实的DOM,有效减少自己的出现),去提高需要更新的效果。
一般这是的html结构
<div id="header">
<h1 class="title">苹果</h1>
<p class="content">柠檬</p>
</div>
这是Virtual DOM的结构,是JavaScript模拟出来的物件,会以下面的格式储存起来
{
tag: "div",
props: {
id: "header"
},
children: [
{
tag: "h1",
props: { className: "title" },
children: ["Apple"]
}, {
tag: "p",
props: { className: "content" },
children: ["lemon"]
}
]
}
下面我们简单模拟一下虚拟dom的流程
- createELement :先使用Virtual DOM提供的createELement方法來生成真是DOM
var count = 0;
var tree = render(count);
var rootNode = createElement(tree);
document.body.appendChild(rootNode);
2、当count变动时 Virtual DOM进行对比 再将差异patch到真实的DOM
count++
var newTree = render(count);
var patches = diff(tree, newTree);
rootNode = patch(rootNode, patches);
tree = newTree;
什么是patch?patch指的是在原有的DOM结构上做异动
关于diff算法
图片来源https://www.cronj.com/blog/di...
传统的diff演算法复杂度为O(n³) 处理100个节点对100万次的比值,Virtual DOM的diff演算算法为O(n)与传统的差异化预测下:
1、Virtual DOM比较相同层级的节点
2、同一层的同一节点再次出现一个唯一的关键,就是避免移动被再次创建。
3、如果发现不见了其子节点也会一并消除,不会再做比对 开发者只要在数据逻辑上运行一次更新机制全部自动处理。
关于diff算法的详细理解,可以持续关注更新。