真实DOM渲染和虚拟DOM渲染
- 真实DOM渲染:在传统前端开发过程中,我们编写的HTML会直接被浏览器渲染,转换成为DOM树渲染到浏览器上。
- 虚拟DOM渲染: 目前市面主流的框架都会引入虚拟DOM来对真实的DOM进行抽象,将真实的DOM抽象为VNode节点方便后续的各种操作。虚拟DOM具有效率更高、逻辑更清晰、操作更方便、提供来跨平台的能力等优势。采用虚拟DOM之后我们能够使用使用JavaScript来表达更多的逻辑,减少js代码对真实DOM的操作。
虚拟DOM
整个Vue的渲染系统都是基于“虚拟DOM”这个概念构建的。下面这段名词解释摘取自官方,我认为是最好的解释:
虚拟 DOM (Virtual DOM,简称 VDOM) 是一种编程概念,意为将目标所需的 UI 通过数据结构“虚拟”地表示出来,保存在内存中,然后将真实的 DOM 与之保持同步。这个概念是由 React 率先开拓,随后被许多不同的框架采用,当然也包括 Vue。
可能上面这种概念太抽象了,我们可以直接来看一下一个虚拟DOM节点在代码中是怎么表示的(该示例来自官方):
const vnode = {
type: 'div',// 节点类型
props: { // 节点属性
id: 'hello'
},
children: [ // 子节点
/* 更多 vnode */
]
}
一个vnode代表的就是一个虚拟节点,是一个JavaScript对象。上面这个vnode表示了一个div元素,id为hello,children存放的是它的子节点(也可以是一个字符串、模板语法等等),自己点也是一个vnode对象,vue的运行时渲染器会根据这些vnode的树形结构遍历渲染整个虚拟DOM树,凭此构建出一个正式的DOM树,这个过程被称之挂载(mount)。
DOM的更新(patch)是通过渲染器对两个相同的虚拟DOM比较来完成的,这个过程中diff算法起到了至关重要的作用,在这里不展开讲。Vue或者说现在流行的框架通过虚拟DOM让我们从烦杂的DOM操作中脱离出来,使得我们的开发更加灵活。
三大核心
- compiler: 编译系统。Vue模版通过该系统被编译为渲染函数(一个用来返回虚拟DOM树的函数)
- Runtime:运行时模块,也称为渲染器模块。编译完成之后由运行时模块进行渲染,它会调用runder函数遍历返回的虚拟DOM树,并基于这个树创建真实的DOM节点。下面图一是编译渲染模块的简化工作流程图,图二是Runtime在源码中对应的位置;
图一:
图二
- Reactivity:响应式系统。下图是响应式源对应的文件位置;
下面是官方文档所提供的一个流程图,演示来从编译到实例挂载的过程:
参考文献: Vue官方文档