虚拟DOM的实现原理与优缺点
前⾔:
虚拟DOM就是为了解决浏览器性能问题⽽被设计出来的。如前,若⼀次操作中有10次更新DOM的动作,虚拟DOM不会⽴即操作DOM,⽽是将这10次更新的diff内容保存到本地⼀个JS对象中,最终将这个JS对象⼀次性attch到DOM树上,再进⾏后续操作,避免⼤量⽆谓的计算量。所以,⽤JS对象模拟DOM节点的好处是,页⾯的更新可以先全部反映在JS对象(虚拟DOM)上,操作内存中的JS对象的速度显然要更快,等更新完成后,再将最终的JS对象映射成真实的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这款软件也可以为我们指出两个对⽐⽂件的不同之处
虚拟DOM的优缺点:
优点:
保证性能下限: 虚拟DOM可以经过diff找出最⼩差异,然后批量进⾏patch,这种操作虽然⽐不上⼿动优化,但是⽐起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限
⽆需⼿动操作DOM: 虚拟DOM的diff和patch都是在⼀次更新中⾃动进⾏的,我们⽆需⼿动操作DOM,极⼤提⾼开发效率
跨平台: 虚拟DOM本质上是JavaScript对象,⽽DOM与平台强相关,相⽐之下虚拟DOM可以进⾏更⽅便地跨平台操作,例如服务器渲染、移动端开发等等
缺点:
⽆法进⾏极致优化: 在⼀些性能要求极⾼的应⽤中虚拟DOM⽆法进⾏针对性的极致优化,⽐如VScode采⽤直接⼿动操作DOM的⽅式进⾏极端的性能优化