虚拟DOM的实现原理和优劣对比


Web界面由DOM树(树的意思是数据结构)来构建,当其中一部分发生变化时,其实就是对应某个DOM节点发生了变化。

虚拟DOM就是为了解决浏览器性能问题而被设计出来的。如前,若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一次性attch到DOM树上,再进行后续操作,避免大量无谓的计算量。所以,用JS对象模拟DOM节点的好处是,页面的更新可以先全部反映在JS对象(虚拟DOM)上,操作内存中的JS对象的速度显然要更快,等更新完成后,再将最终的JS对象映射成真实的DOM,交由浏览器去绘制。

虚拟DOM概念随着react的诞生而诞生,由facebook提出,其卓越的性能很快得到广大开发者的认可;继react之后vue2.0也在其核心引入了虚拟DOM的概念;

本章节,我们来逐步学习虚拟DOM的原理及其性能的优劣知识点梳理:

什么是虚拟DOM ?

虚拟dom可以看作是一个使用javascript模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息,如下图所示:

为什么使用虚拟DOM ?

之前使用原生js或者jquery写页面的时候会发现操作DOM是一件非常麻烦的一件事情,往往是DOM标签和js逻辑同时写在js文件里,数据交互时不时还要写很多的input隐藏域,如果没有好的代码规范的话会显得代码非常冗余混乱,耦合性高并且难以维护。

另外一方面在浏览器里一遍又一遍的渲染DOM是非常非常消耗性能的,常常会出现页面卡死的情况;所以尽量减少对DOM的操作成为了优化前端性能的必要手段,vdom就是将DOM的对比放在了js层,通过对比不同之处来选择新渲染DOM节点,从而提高渲染效率。

patch函数

patch函数的执行分为两个阶段,两次传递的参数都是两个

第一阶段为虚拟dom的第一次渲染,传递的两个参数分别是放真实DOM的container和生成的vnode,此时patch函数的作用是用来将初次生成的真实DOM结构挂载到指定的container上面。

第二阶段传递的两个参数分别为vnode和newVnode,此时patch函数的作用是使用diff算法对比两个参数的差异,进而更新参数变化的DOM节点;

可以发发现h函数和patch函数在cnabbdom中实现vdom到真实DOM的转化起到了至关重要的作用,那么还有一个很重要的环节,patch函数中是怎么样实现对比两个vnode从而实现对真实DOM的更新的呢,这里还要提一下snabbdom的另外一个核心算法,即diff算法。

diff算法

其实在我们日常开发中我们都在接触类似与diff算法的一些软件,比如svn可以看到当前代码和svn服务器上代码的不同之处,再如Beyond Compare这款软件也可以为我们指出两个对比文件的不同之处

但是此处是如何实现对vnode的对比的呢?参考以下代码:

let children = vnode.children || []
let newChildren = newVnode.children || []children.forEach(function(childrenVnode, index) {var newChildVnode = newChildren[index]  // 首先拿到对应新的节点if (childrenVnode.tag === newChildVnode.tag) {    // 判断节点是否相同updateChilren(childrenVnode, newChildVnode)   // 如果相同执行递归,深度对比节点} else {repleaseNode(childrenVnode, newChildVnode)    // 如果不同则将旧的节点替换成新的节点}
})
}function repleaseNode(vnode, newVnode) {    // 节点替换函数let elem = vnode.elemlet newEle = createElement(newVnode)
}

总结

  • 虚拟DOM的实现原理:

    • 虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象
    • 状态变更时,记录新树和旧树的差异
    • 最后把差异更新到真正的dom中
  • 虚拟DOM的优劣如何?
    • 优点:
    • 保证性能下限: 虚拟DOM可以经过diff找出最小差异,然后批量进行patch,这种操作虽然比不上手动优化,但是比起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限
    • 无需手动操作DOM: 虚拟DOM的diff和patch都是在一次更新中自动进行的,我们无需手动操作DOM,极大提高开发效率
    • 跨平台: 虚拟DOM本质上是JavaScript对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等
    • 缺点:
    • 无法进行极致优化: 在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化,比如VScode采用直接手动操作DOM的方式进行极端的性能优化

虚拟DOM的实现原理和优劣对比相关推荐

  1. 【React深入】深入分析虚拟DOM的渲染原理和特性

    导读 React的虚拟DOM和Diff算法是React的非常重要的核心特性,这部分源码也非常复杂,理解这部分知识的原理对更深入的掌握React是非常必要的. 本来想将虚拟DOM和Diff算法放到一篇文 ...

  2. Patch:虚拟DOM最核心的部分--如何对比虚拟DOM树,以及如果生成真实DOM

    虚拟DOM最核心的部分是patch,它可以将vnode渲染成真实DOM. patch也可以叫做patching算法,通过它渲染真实DOM时,并不会暴力覆盖原有DOM.而是比对新旧俩个vnode之间有哪 ...

  3. vue虚拟DOM原理

    虚拟 DOM(Virtual DOM)是一种用 JavaScript 对象来描述 DOM 树结构的概念,它的实现原理是在 DOM 更新时,通过对比新旧虚拟 DOM,找出需要更新的节点,然后仅更新这些节 ...

  4. web前端面试高频考点——Vue原理(理解MVVM模型、深度/监听data变化、监听数组变化、深入了解虚拟DOM)

    系列文章目录 内容 参考链接 Vue基本使用 Vue的基本使用(一文掌握Vue最基础的知识点) Vue通信和高级特性 Vue组件间的通信及高级特性(多种组件间的通信.自定义v-model.nextTi ...

  5. vue中的虚拟DOM原理

    1.定义: 虚拟DOM其实就是用一个原生的JS对象去描述一个DOM节点,实际上它只是对真实 DOM 的一层抽象.最终可以通过一系列操作使这棵树映射到真实环境上. 相当于在js与DOM之间做了一个缓存, ...

  6. 虚拟Dom的基本理解

    1.概念: 虚拟DOM其实就是用一个原生的JS对象去描述一个DOM节点,实际上它只是对真实 DOM 的一层抽象.最终可以通过一系列操作使这棵树映射到真实环境上. 相当于在js与DOM之间做了一个缓存, ...

  7. React 虚拟DOM

    虚拟DOM 什么是DOM DOM是用一颗逻辑树来表示一个文档,树的每个分支的终点都是一个节点,可以用特定的方式(编写JS.CSS.HTML)来改变这个树的结构,从而改变文档结构.样式或内容. 什么是虚 ...

  8. 26.Vue列表渲染中key的作用与原理(内含虚拟DOM的对比算法详解)

    目录 1.暴露问题,使用index作为key 2.使用唯一标识p.id作为key 3.不写key的配置 4.key的工作原理及虚拟DOM的对比算法 5.总结 25.Vue列表渲染_爱米酱的博客-CSD ...

  9. Vue进阶之Virtual DOM(虚拟DOM) 实现原理

    Vue进阶之Virtual DOM(虚拟DOM) 实现原理 Virtual DOM(虚拟 DOM),是由普通的 JS 对象来描述 DOM 对象,因为不是真实的 DOM 对象,所以叫 Virtual D ...

最新文章

  1. Java的字符串常量池
  2. 有望取代Spark,Michael Jordan和Ion Stoica提出下一代分布式实时机器学习框架Ray牛在哪?...
  3. 深度学习框架TensorFlow(3.变量)
  4. html 文本框数量加减,收藏!js实现input加减
  5. 【转】如何将域中的AD数据导入SharePoint
  6. LeetCode算法入门- String to Integer (atoi)-day7
  7. react-native学习路线总结
  8. 极限编程创始人Ron Jeffries建议开发者放弃敏捷
  9. 前端:常用单词(JS,CSS,HTML)
  10. qmake:未找到命令
  11. PHP数字金额转换成中文大写金额
  12. 【Si24R2F+ Demo板】介绍说明与使用建议
  13. 特殊字符--百度百科
  14. VMC(VMware on AWS)分析
  15. 电镀行业水处理分析:褪镀废水回收重金属,用什么工艺解决
  16. AsyncTask用法
  17. 机器学习入门的书单(数据挖掘、模式识别等一样)转
  18. mshtml与System.Windows.Forms.HtmlElement
  19. 新手站长:成功申请Godaddy域名退款到支付宝全过程
  20. python调用百度翻译api+离线语种检测

热门文章

  1. 第8章 Linux的文件管理(三)
  2. Java 各种文件类型转换的方法
  3. 【Linux】一步一步学Linux——uniq命令(54)
  4. qq管家拦截域名检测,qq浏览器域名检测,qq域名检测源码
  5. 《福尔摩斯探案集》摘录
  6. 阿里云联合通达信科等上百家知名软件服务商发布金盾宣言
  7. 纯前端实现excel下载功能
  8. Spring Boot 多线程数据同步
  9. C++笔记一瞥_艾孜尔江撰
  10. 【信源编码技术】实验2-Huffman编码