面试官:什么是虚拟DOM?谈谈你的理解

219 阅读2分钟

什么是虚拟DOM?

虚拟 DOM (Virtual DOM)这个概念相信大家都不陌生,从ReactVue虚拟DOM为这两个框架都带来了跨平台的能力(React-Native 和 Weex)。

实际上它只是一层对真实DOM的抽象,以JavaScript 对象 (VNode 节点) 作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作使这棵树映射到真实环境上,在Javascript对象中,虚拟DOM 表现为一个 Object对象。并且最少包含标签名 (tag)、属性 (attrs) 和子元素对象(children) 三个属性,不同框架对这三个属性的命名可能会有差别,创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应。

为什么需要虚拟DOM?

DOM是很慢的,其元素非常庞大,页面的大多数性能问题都是由DOM操作引起的。 真实的DOM节点,哪怕一个小div也包含着很多的属性,

      var div = document.createElement("div");
      let str = "";
      for (let key in div) {
        str = str + key + " ";
      }
      console.log(str);

image.png 由此可见,操作DOM的代价仍旧是昂贵的,频繁操作还是会出现页面卡顿,影响用户的体验

举个例子:

你用传统的原生apijQuery去操作DOM时,浏览器会从构建DOM树开始从头到尾执行一遍流程。当你在一次操作时,需要更新10个DOM节点,浏览器没这么智能,收到第一个更新DOM请求后,并不知道后续还有9次更新操作,因此会马上执行流程,最终执行10次流程。

而通过VNode,同样更新10个DOM节点,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地的一个js对象中,最终将这个js对象一次性attachDOM树上,避免大量的无谓计算

很多人认为虚拟 DOM 最大的优势是 diff 算法,减少 JavaScript 操作真实 DOM 的带来的性能消耗。虽然这一个虚拟 DOM 带来的一个优势,但并不是全部。虚拟 DOM 最大的优势在于抽象了原本的渲染过程,实现了跨平台的能力,而不仅仅局限于浏览器的 DOM,可以是安卓和 IOS 的原生组件,可以是近期很火热的小程序,也可以是各种GUI。