这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战
在Vue
的渲染流程中,render
函数绝对是核心流程,AST
和虚拟DOM
在生成render
函数的过程中扮演着重要的角色,部分前端初学者也容易将AST和虚拟DOM混淆,因此在本文主要介绍一下两者以及为何使用虚拟DOM
概念差异
AST语法树概念
象语法树 (Abstract Syntax Tree),简称 AST,它是源代码语法结构的一种抽象表示。 它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。
虚拟DOM概念
Virtual DOM (虚拟 DOM),是由普通的 JS 对象来描述 DOM 对象,因为不是真实的 DOM 对象,所以叫 Virtual DOM
通过概念可以总结:AST是对原生语法结构的描述,虚拟DOM是对于DOM节点的描述,两者共同点都是使用对象来进行描述
结果差异
现在有这个一段HTML
<div id="app">
<p>{{name}}</p>
</div>
在Vue
中生成的对应AST
{
"type": 1,
"tag": "div",
"attrsList": [
{
"name": "id",
"value": "app",
"start": 5,
"end": 13
}
],
"attrsMap": {
"id": "app"
},
"rawAttrsMap": {
"id": {
"name": "id",
"value": "app",
"start": 5,
"end": 13
}
},
"children": [
{
"type": 1,
"tag": "p",
"attrsList": [],
"attrsMap": {},
"rawAttrsMap": {},
"parent": "[Circular ~]",
"children": [
{
"type": 2,
"expression": "_s(name)",
"tokens": [
{
"@binding": "name"
}
],
"text": "{{name}}",
"start": 22,
"end": 30,
"static": false
}
],
"start": 19,
"end": 34,
"plain": true,
"static": false,
"staticRoot": false
}
],
"start": 0,
"end": 41,
"plain": false,
"attrs": [
{
"name": "id",
"value": "\"app\"",
"start": 5,
"end": 13
}
],
"static": false,
"staticRoot": false
}
在Vue
中生成的对应render
函数
_c('div', {
attrs: {
"id": "app"
}
}, [_c('p', [_v(_s(name))])])
虚拟DOM通过调用render
函数中的_c
、_v
等函数创建,最终形式如下图
选择虚拟DOM原因
为何Vue
选择使用虚拟DOM而不是直接使用真实的DOM呢?
- 保证性能下限
首先真实的DOM上包含了太多无用的属性,使用虚拟DOM可以大大的减少不必要的属性存在,可以很好的释放内存的压力
其次操作真是DOM是非常消耗性能的一件事情,由于JS是单线程的,当我们去操作DOM的时候无论是获取还是更改一些属性的时候,都会引起浏览器的render
,若是频繁或者不恰当的操作DOM则会引起严重的性能问题,因此直接操作DOM的代价是非常大的。采用虚拟DOM可以将全部的修改一次性的更新到页面,不用修改一次而导致浏览器render
一次
虽然虚拟DOM很好,但是并不是说其就真的拥有很好的性能,不能盲目夸虚拟DOM性能,因为在大量的虚拟DOM进行diff
算法比较的时候并不能很好的保证性能
- 提高开发体验
想一想在刀耕火种或者JQ
时代我们前端被DOM支配的恐惧,不用操作DOM是一件多么幸福的事情,Vue
释放了我们直接操作DOM的双手,让我们可以去做更多的事情
- 跨端
由于虚拟DOM的存在,Vue
不仅可以用于浏览器,还在小程序、weex
等领域发光发热