声明:这只是一篇学习笔记
什么是虚拟DOM
根据之前React文档里面所描述的,虚拟dom是一种编程概念。它本质上跟js没有任何的关系,只要让某种东西在进行排列组合后能将真实dom的结构描述出来,那这个东西就是虚拟DOM。
举个例子:如果你使用不同种类的石头代表不同的DOM节点,文本节点等,再将其进行树状的排列,使其能将真实DOM的结构表达出来,那么这些石头就是一个个的虚拟DOM。
所以虚拟dom跟React,Vue等框架的关系就显而易见了: react和vue使用了js对象作为虚拟DOM的具体实现。换句话说,前者是一种思想,后者使用js对象具体实现了它。
它的优势
1. 高效性
事实上,在初次渲染页面的时候,虚拟dom的存在并没有什么优势,因为它最终还是会装换成真实DOM节点,可以说,它比直接渲染真实DOM节点可能还多了一个步骤。如下:
直接渲染真实DOM(使用innerHTML):
- 解析字符串
- 变成真实dom加载到页面上(直接舍弃之前的DOM树)
使用虚拟DOM:
- 解析字符串(vue)
- 创建虚拟DOM树
- 变成真实DOM加载到页面上
但是它的用武之地并非是在初次渲染页面上,而是在组件更新导致重新渲染的时候。
我们先来设想一下如果每次页面组件的更新都会导致整个页面重新被渲染,那这个代价会有多高昂。
-
如果我点击一个按钮会导致组件展示的值加1,那我快速点击一百下呢?如果组件少还好,如果页面中有10000个组件的话,全部重新渲染,电脑都得被干冒烟(狗头)。
这与浏览器渲染原理有关,页面整体的重排重绘需要耗费很长的时间。
那么虚拟dom为什么高效:
-
通过diff算法,它的存在可以实现当组件发生变化时,只重新渲染
发生变化的组件。因此它只需要局部的重排重绘(如果需要的话)。因为无论是React或Vue在进行diff比较的时候,在某些情况下都会直接使用原来的真实dom进行复用,还省去了创建真实DOM的过程。 -
当多个状态更新同时发生时,React 会尝试将它们合并成一个批次来进行处理。这意味着即使有多个独立的状态变化,也只会触发一次完整的渲染流程。
2. 多平台渲染的抽象能力
虚拟dom的优势还不只是高效,它还有一个非常牛的点: 多平台渲染的抽象能力
UI = fn(state) 这个公式可拆分为
- 根据自变量的变化计算出UI
- 根据UI变化执行具体的宿主环境的API
就像上文说的,虚拟dom只是一个编程概念,不与具体的宿主环境绑定。根据不同的宿主环境能执行不同的渲染代码。因此虚拟dom可以广泛应用于各种宿主环境。无论是服务器端、桌面应用、移动开发还是嵌入式系统,只要存在需要频繁更新用户界面的需求,虚拟 DOM 都能提供显著的性能提升和更好的开发体验。
比方说:对react而言
- 在浏览器端,nodeJs端,使用ReactDOM包去连接
React虚拟DOM和实际浏览器DOM的桥梁 - 在Native端,使用ReactNative包
- ...