虚拟DOM
到底什么是虚拟DOM呢?
-
Virtual DOM 其实就是一棵以 JavaScript 对象( VNode
节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象。最终可以通过一系列操作使这棵树映射到真实环境上 -
简单来说,可以把Virtual DOM 理解为一个简单的JS对象,并且最少包含标签名( tag)、属性(attrs)和子元素对象(children)三个属性。不同的框架对这三个属性的命名会有点差别
诞生的原因
因为 操作DOM 的代价比较高 , 如果频繁地操作 DOM ,会导致性能的下降 , 所有如果我们把 操作DOM的结果先放入 虚拟DOM中 , 然后操作完后 , 再把 虚拟DOM 渲染成 真实 DOM ,一次性append 到相应的节点中 ,便可以优化性能。
举个栗子:
就是下图所示的这个,详细的阐述了模板 → 渲染函数 → 虚拟DOM树 → 真实DOM的一个过程
Virtual DOM 作用是什么?
虚拟DOM的最终目标是将虚拟节点渲染到视图上
。但是如果直接使用虚拟节点覆盖旧节点的话,会有很多不必要的DOM操作。例如,一个ul标签下很多个li标签,其中只有一个li有变化,这种情况下如果使用新的ul去替代旧的ul,因为这些不必要的DOM操作而造成了性能上的浪费。
为了避免不必要的DOM操作,虚拟DOM在虚拟节点映射到视图的过程中,将虚拟节点与上一次渲染视图所使用的旧虚拟节点(oldVnode)做对比,找出真正需要更新的节点来进行DOM操作,从而避免操作其他无需改动的DOM。
其实虚拟DOM在Vue.js主要做了两件事:
- 提供与真实DOM节点所对应的虚拟节点vnode
- 将虚拟节点vnode和旧虚拟节点oldVnode进行对比,然后更新视图
为何需要Virtual DOM?
- 具备跨平台的优势
- 操作 DOM 慢,js运行效率高。我们可以将DOM对比操作放在JS层,提高效率。
- 提升渲染性能
diff 算法
diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom。
diff 算法包括几个步骤:
-
用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
-
当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
-
把所记录的差异应用到所构建的真正的DOM树上,视图就更新了
下面我们看图理解一下就好多了