目前前端开发框架 2 巨头React和Vue都使用到了虚拟 DOM(virtual dom)技术,以及现在面试基本都会问到的问题:你了解虚拟 DOM 吗?那么,现在我就来简单的聊一聊虚拟 DOM
为什么要用虚拟 DOM
在 web 开发中,操作 DOM 是非常损耗性能的,由于浏览器 JS 是单进程,如果在页面渲染方面占用了太长时间,那么在功能影响方法就会堵塞,十分影响用户体验。同时,现代 web 应用越来越庞大,功能也更加复杂,以及 AJAX 的使用,页面也能响应更多的用户操作,页面的改变也越来越大,如果使用以前的 JQuery,那么 web 开发工作将会越发复杂,需要不停的响应用户的操作,更新数据,更新页面,从开发维护到应用性能上都很受影响。
如何提高开发效率,减少维护成本以及提高 web 应用性能呢?React给我们带来了virtual dom
通过分析可以发现,这是一个 DIV 标签,同时含有 2 个 P 标签,我们首先通过tagName创建DOMElement,如果没有tagName我们创建TextNode,然后为 Element 添加属性以及子元素,我们可以设计一个 render 函数来解析它,render 函数接收 vNode 以及解析后挂载的位置:
function render(vNode, dom) {
// 文本标签
if (isString(vNode)) {
const text = document.createTextNode(vNode)
dom.appendChild(text)
// 数组
} else if (isArray(vNode)) {
vNode.forEach(child => render(child, dom))
// 对象
} else if (isObject(vNode)) {
const { tagName, props, children } = vNode
const root = document.createElement(tagName)
dom.appendChild(root)
if (props) {
addAttribute(root, props)
}
if (isArray(children)) {
children.forEach(child => render(child, root))
}
}
}
目前前端开发框架 2 巨头
React
和Vue
都使用到了虚拟 DOM(virtual dom)技术,以及现在面试基本都会问到的问题:你了解虚拟 DOM 吗?那么,现在我就来简单的聊一聊虚拟 DOM为什么要用虚拟 DOM
在 web 开发中,操作 DOM 是非常损耗性能的,由于浏览器 JS 是单进程,如果在页面渲染方面占用了太长时间,那么在功能影响方法就会堵塞,十分影响用户体验。同时,现代 web 应用越来越庞大,功能也更加复杂,以及 AJAX 的使用,页面也能响应更多的用户操作,页面的改变也越来越大,如果使用以前的 JQuery,那么 web 开发工作将会越发复杂,需要不停的响应用户的操作,更新数据,更新页面,从开发维护到应用性能上都很受影响。
如何提高开发效率,减少维护成本以及提高 web 应用性能呢?
React
给我们带来了virtual dom
什么是虚拟 DOM
虚拟 DOM 就是使用 JS 模拟出来的 DOM 结果,比如一段简单的 HTML:
使用 JS 我们可以这样表示:
对于更复杂的 HTML 标签,我们在 JS 里都可以用以上的结构来模拟:
tagName
、props
和children
。这样,我们就可以用 JS 来描述页面 UI 了。如何解析虚拟 DOM
有了虚拟 DOM 之后,我们页面要呈现出来还是需要转换为 HTML 标签才行,那么现在就是如何解析虚拟 DOM 了,现在,我们有这样一段 VNode:
通过分析可以发现,这是一个 DIV 标签,同时含有 2 个 P 标签,我们首先通过
tagName
创建DOMElement
,如果没有tagName
我们创建TextNode
,然后为 Element 添加属性以及子元素,我们可以设计一个 render 函数来解析它,render 函数接收 vNode 以及解析后挂载的位置:这里还有一些判断 JS 类型的工具函数:
在属性解析里面,我们还可能会有事件需要设置,我们编写一个简单的属性设置函数:
使用虚拟 DOM
这样一个简单的虚拟 DOM 解析函数就写好了,它可以根据虚拟 DOM 渲染成真实的 UI 界面,如何测试并使用它呢?我们可以使用 Jason Miller 开发的 htm,它可以无需编译即可在浏览器中使用,十分简单,使用如下:
这样就可以轻松把我们的虚拟 DOM 渲染到页面上了。但是仅仅这样使用的话还不如直接插入
innerHTML
,在效率上并没有很大的提高,其实虚拟 DOM 的优势还需要结合diff
算法才能体现,现在我们只是实现了虚拟 DOM 的解析工作。以上只是一个简单的虚拟 DOM 示例,实际中,我们可能还会包括类组件,函数组件等,我们需要对他们进行一一的解析,后面将会逐步展开。
其实,虚拟 DOM 真正的意义在于使用函数式来开发 UI,使得
UI=h(vNode)
,其中的 h 函数就是我们解析 VNOde 的函数,并且其他与 UI 相关的绘制工作我们都可以使用函数式来完成,唯一需要修改的就是我们的解析函数了,无论怎么样UI=h(vNode)