网站首页 > 技术文章 正文
面试题:请你阐述一下对vue虚拟dom的理解
1. 什么是虚拟dom?
虚拟dom本质上就是一个普通的JS对象,用于描述视图的界面结构 如下:
{
tag: 'div',
props: {
id: 'app'
},
chidren: [
{
tag: 'p',
props: {
className: 'text'
},
chidren: [],
text: 'hello world!!!'
}
]
}
复制代码
生成的html代码是这样的:
<div id="app">
<p class="text">hello world!!!</p>
</div>
复制代码
在vue中,每一个组件其实都会被vue编译成一个vNode(虚拟dom),每个组件都有一个render函数,每个render函数都会返回一个虚拟dom树,这也就意味着每个组件都对应一棵虚拟DOM树
2. 为什么需要虚拟dom?
在vue中,渲染视图会调用render函数,这种渲染不仅发生在组件创建时,同时发生在视图依赖的数据更新时。如果在渲染时,直接使用真实DOM,由于真实DOM的创建、更新、插入等操作会带来大量的性能损耗,从而就会极大的降低渲染效率。
这里来做一个简单的测试,创建等量的js对象和等量的dom对象,看看消耗的时间分别是多少。
普通对象,在数组放入10w个对象,消耗时间是 40ms
创建一个普通的dom对象,在数组中放入,消耗的时间是132s;大概是普通对象的4倍
因此,在上述的列子中,从创建对象中可以看出来,创建真实的dom其实是花时间的,这也只是一开始的创建,如果在更新中,频繁的更新真实的dom,还会引起浏览器的重绘和浏览器的重排,使用虚拟dom来替代真实dom,主要为解决渲染效率的问题
3. 虚拟dom是如何转换为真实dom的?
在一个组件实例首次被渲染时,它先生成虚拟dom树,然后根据虚拟dom树创建真实dom,并把真实dom mount(挂载)到页面中合适的位置,此时,每个虚拟dom便会对应一个真实的dom。
如果一个组件受响应式数据变化的影响,需要重新渲染时,它仍然会重新调用render函数,创建出一个新的虚拟dom树,用新树和旧树对比,通过对比,vue会找到最小更新量,然后更新必要的虚拟dom节点,最后,这些更新过的虚拟节点,会去替换它们对应的真实dom
这样一来,就保证了对真实dom达到最小的改动。
通过这里,咋们可以知道,虚拟dom不是一定比真实dom快的,当我们第一次创建的时候,你虚拟dom多生成了一道,而我的真实dom是直接挂载的,然后还有是如果页面结构简单,真实dom也是要比虚拟dom更快的!
4. 模板和虚拟dom的关系
vue框架中有一个compile模块,它主要负责将模板转换为render函数,而render函数调用后将得到虚拟dom。
编译的过程分两步:
- 将模板字符串转换成为AST
- 将AST转换为render函数
如果使用传统的引入方式,则编译时间发生在组件第一次加载时,这称之为运行时编译。
如果是在vue-cli的默认配置下,编译发生在打包时,这称之为模板预编译。
编译是一个极其耗费性能的操作,预编译可以有效的提高运行时的性能,而且,由于运行的时候已不需要编译,vue-cli在打包时会排除掉vue中的compile模块,以减少打包体积
模板的存在,仅仅是为了让开发人员更加方便的书写界面代码
vue最终运行的时候,最终需要的是render函数,而不是模板,因此,模板中的各种语法,在虚拟dom中都是不存在的,它们都会变成虚拟dom的配置
5. 拓展
在聊到虚拟dom的时候,其实vue也是参考一个虚拟dom库( snabbdom)的更新操作的。
看到上面的h是不是感觉很熟悉呀,熟悉就行动起来,源码整起来
猜你喜欢
- 2024-10-29 Vue3 - 表单的输入与绑定(vue实现表单)
- 2024-10-29 67、Vue 中如何实现一个虚拟 DOM?说说你的思路(高薪常 问)
- 2024-10-29 Vue中配合clipboard.js实现点击按钮复制内容到剪切板
- 2024-10-29 「绍棠」 Vue面试整理 一(vue项目面试中怎样去说)
- 2024-10-29 深入浅出虚拟 DOM 和 Diff 算法,及 Vue2 与 Vue3 中的区别
- 2024-10-29 这大概是理解VUE的虚拟DOM最简单的文章了
- 2024-10-29 vue-这应该是最基础了吧(vue vh)
- 2024-10-29 深入了解Vue 3中onBeforeMount钩子和DOM元素的获取时机
- 2024-10-29 Vue.js教程(六)--Vue实例的属性和方法
- 2024-10-29 Vue中多个元素、组件的过渡及列表过渡的方法示例
- 11-26Win7\8\10下一条cmd命令可查得笔记本电脑连接过的Wifi密码
- 11-26一文搞懂MySQL行锁、表锁、间隙锁详解
- 11-26电脑的wifi密码忘记了?一招教你如何找回密码,简单明了,快收藏
- 11-26代码解决忘记密码问题 教你用CMD命令查看所有连接过的WIFI密码
- 11-26CMD命令提示符能干嘛?这些功能你都知道吗?
- 11-26性能测试之慢sql分析
- 11-26论渗透信息收集的重要性
- 11-26如何查看电脑连接过的所有WiFi密码
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)