我们都知道 Vue 和 React 内部都使用了虚拟 DOM,我最近刚刚开始梳理虚拟 DOM 的相关知识,下面是我梳理的笔记,简单明了、清晰易懂,建议收藏。
大纲
- 虚拟 DOM 的前情提要
- 为什么使用虚拟 DOM
- 什么是虚拟 DOM(Virtual DOM)
- 虚拟 DOM 的作用
一、虚拟 DOM 的前情提要
当浏览器获取了一个 HTML 文档后,浏览器内核 webkit 的 WebCore 层中的 HTML 引擎会将该文档解析为 DOM 树,解析出的 DOM 树会交给同处在 WebCore 层的 DOM 模块负责管理,这里的 DOM 树就是真实 DOM。
我们在前端的刀耕火种的时代,都是直接使用 JavaScript 直接操作 DOM,但 Dom 树实际是由 DOM 模块负责管理的,浏览器内核中单独有一块内存来存储 DOM 树,但 JavaScript 引擎和这块内存并无关系,也就是它并不能直接的操作真实的 DOM 树。
为了给予 JavaScript 操作 DOM 的能力,浏览器在全局对象 window 上为 JavaScript 封装了一个 document 对象,在这个对象上提供了大部分 DOM 操作 API(接口由 C++ 实现)。
二、为什么使用虚拟 DOM
当我们通过这些接口操作 DOM 时, JavaScript 并没有直接和 DOM 模块交互,它调用浏览器的 DOM API后,是由浏览器来操作 DOM 模块,再把操作结果返回给 JavaScript 引擎的,而正是由于 JavaScript 需要借助 DOM 接口才能操作真实 DOM,所以操作真实 DOM 的代价是巨大的:
- JavaScript 直接调用的是 C++ 实现的接口;
- 真实 DOM 树的节点较多,体积较为庞大,真实 DOM 操作过程资源开销成本很大;
- 修改真实 DOM 经常导致页面重绘,操作 DOM 越多,网页性能越差;
历史原因,JavaScript 出现在 DOM 之后,导致设计上 DOM 不能够由 JavaScript 管理,如果要 JavaScript 管理 DOM,浏览器内核必须重构,这在当时显然不可能。
综上,我们如何有效减少对真实 DOM 的操作,是前端性能优化很重要的一部分,而使用虚拟 DOM 是目前非常流行且有效的解决方案。
三、什么是虚拟 DOM(Virtual DOM)
虚拟 DOM 就是由普通的对象描述的 DOM 对象,因为不是真实的 DOM,所以叫做虚拟 DOM。
由前情提要我们能够知道,创建/操作真实 DOM ,资源开销是特别大的,而仅仅使用普通对象来模拟虚拟 DOM,能够有效减少对真实 DOM 的操作,从而提升网页性能。
四、虚拟 DOM 的作用
由前情提要我们能够知道,创建/操作真实 DOM ,资源开销是特别大的,因此:
- 我们可以在状态发生变化需要更新视图时,使用虚拟 DOM 在内存中完成修改,减少对真实 DOM 的直接操作次数,维护视图和状态的关系;
- 我们还可以通过 diff 算法比较修改后的虚拟 DOM 和修改前的真实 DOM 的差异,只需去更新真实 DOM 中发生变化的位置,较少重绘次数,提升渲染性能;
- 其它:虚拟 DOM 还作用于如 服务端渲染 SSR、原生应用 React Native、小程序 uni-app 等其它方面;
前端源码原理系列:第 1 篇
下期预告:
Vue 内部的虚拟 DOM 是改造了一个开源库:Snabbdom,所以我们可以拿它开刀,先从 Snabbdom 的基本使用开始,再逐行分析 Snabbdom 的源码,从中了解虚拟 DOM 的工作过程和原理。
本期名词:
重绘、diff 算法、SSR、React Native、uni-app