虚拟DOM

98 阅读2分钟

虚拟DOM

虚拟DOM 本质是一个JS对象,用于描述视图的界面结构

在vue中,每个组件都有一个render函数,每个render函数都会返回一个虚拟DOM树,这也就意味着每个组件都对应一颗虚拟DOM树

为什么需要虚拟DOM?

在vue中,视图渲染会调用render函数,这种渲染不仅发生在组件创建时,同时发生在视图依赖的数据更新时。如果在渲染时,直接使用真实DOM,由于真实DOM的创建、更新、插入等操作会带来大量的性能损耗,从而降低渲染效率(打印虚拟DOM 和 真实DOM,发现真实DOM 的属性也远远多于虚拟DOM)

虚拟DOM如何转换为真实DOM?

在一个组件实例首次被渲染时,它会先生成虚拟DOM树,然后根据虚拟DOM创建真实DOM,并把真实DOM挂载到页面中,此时,每个虚拟DOM便会对应一个真实的DOM。

如果一个组件受响应式数据变化的影响,需要重新渲染时,它仍会重新调用render函数,创建出一个新的虚拟DOM树,用新树和旧树对比,找到最小更新量,然后更新必要的虚拟DOM节点,再通过节点来修改真实DOM(实际是直接使用新树,抛弃旧树,然后只更新必要的真实DOM)

模板和虚拟DOM的关系

vue框架中有一个compile模块,它主要负责将模板转为render函数,而render函数调用后将得到虚拟DOM。

编译的过程分为两步:

1. 将模板字符串转换为AST(抽象语法树)
1. 将AST转换为render函数

如果使用传统的引入方式或 vue-cli的配置中开启了runtimecompiler:true,则编译时间发生在组件第一次加载时,这称之为运行时编译。 如果是在 vue-cli的默认配置下,编译发生在打包时,这称之为模板预编译.

编译是一个极其耗费性能的操作,预编译可以有效的提高运行时的性能,而且,由于运行的时候已不需要编译,vue-cli在打包时会排除掉vue 中的compile 模块,以减少打包体积

模板的存在,仅仅是为了让开发人员更加方便的书写界面代码

vue最终运行的时候,最终需要的是render函数,而不是模板,因此,模板中的各种语法,在虚拟dom中都是不存在的,它们都会变成虚拟dom的配置