快看,VUE对你的页面做了什么

原创
10/27 08:43
阅读数 14
转载本文需注明出处:微信公众号EAWorld,违者必究。

讲过了Vue的响应式原理,那就不得不说说和它息息相关的diff算法的实现。响应式系统会监听发生改变的数据并将相关组件重新渲染。其实,即便没有响应式,也可以通过操作DOM节点来更新数据显示,但是这样做的代价实在太大,降低页面性能,因此产生了Virtual DOM,它的主要思想是利用JavaScript对象按照真实的DOM结构来抽象出一个虚拟DOM结构,并在需要更新某些节点时,进行新旧对比,找出需要更新的节点后,仅仅对需要重新渲染的节点进行更新,这样就大大提高页面性能。不仅仅是Vue,React也使用了Virtual DOM技术来优化渲染效率。

Virtual DOM中负责将新旧DOM树中的节点进行对比并找出发生变更的节点这一工作是由diff来进行的,diff是Virtual DOM较为核心的部分,要对比两棵层级复杂的DOM树,diff的时间复杂度直接影响了新旧节点替换的性能。Vue实践的diff算法仅仅对同级的节点进行比较,因此时间复杂度为O(n)。如下图,diff算法仅对颜色相同的方框中的节点进行对比。


Diff算法首先对比新旧节点,这一对比仅在同层节点间进行。由于对比过程源码比较复杂且篇幅巨大,有兴趣的同学可以去github上看看,这里仅对算法进行解析,因此就不搬运源码了。

需要说明一下,在接下来的对比算法中,相同节点的概念,指的是两个节点的key、tag等在第一次渲染时打上的各种标识唯一DOM界的的标记、属性均一致,而不是包含它所带的值,样式颜色等。Patch操作说的是将两个节点进行对比将发生变化的一些属性更新,如果两个节点均包含子节点,那么对他们的子节点同样进行diff对比。在找出同层的两组新旧节点后,分别为他们打上开始和结束的标志,在对比过程中,开始和结束的标志不断向中间靠拢,直到新节点队列或旧节点队列中有一个的开始标志到结束标志之后,那么对比就完成了,整个对比过程如下图:


算法首先将四个被打了标记的节点做如下六种情况对比:

一、NewStart和OldStart

如果是同一节点那么直接将这两个节点进行patch操作,NewStart和OldStart标志后移到下一个节点

二、NewStart和OldEnd

如果是同一节点,将OldEnd节点移到OldStart前,标志前移一个节点,NewStart后移一个节点


三、NewEnd和OldStart

如果是同一节点,将OldStart节点移到OldEnd后,OldStart后移一个节点,NewEnd前移一个节点



四、NewEnd和OldEnd

如果是同一节点那么直接将这两个节点进行patch操作

五、与NewStart相同的节点在旧节点队列中

如果以上情况皆不满足,那么就在旧的节点队列中进行一次遍历对比,找出与NewStart相同的节点,后将该节点前移到OldStart前


六、旧节点队列中无与NewStart相同的节点

如果在旧的节点队列中找不到与NewStart相同的节点,那么就直接在OldStart前直接插入NewStart节点。

按照上面的规则一直对比,直到NewStart到NewEnd相遇或OldStart到OldEnd相遇,此时如果新节点队列中仍有没匹配到的节点,那么就将它们插入旧的节点队列中去,如果旧的节点队列中仍有未匹配到的节点,那么就删掉他们。


在完成对比后,将新的DOM树也就完成了一次更新。

Vue的diff算法主要实现思路大致如此,如果要完整的了解他还是需要阅读大量的源码的,有进阶想法的同学可以去看看。

VUE框架相对学习成本低,易上手且高效灵活在企业项目开发中比较受欢迎。当前,普元的DevOps、微服务、容器云等产品前端技术均使用了VUE框架。学习其底层运行原理还是有助于提升开发人员的编码技能的。

推荐阅读

DevOps之动态表单——优雅地把工作量甩给后端
那些Vue开发遇到的坑---响应式系统
DevOps平台之看板设计

关于作者夏夏,前端工程师,参与普元DevOps产品开发,以及微服务、容器云等产品开发,负责前端页面设计、架构搭建等工作。善于架构搭建、组件封装及相关算法设计。


关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享。长按二维码关注!

本文分享自微信公众号 - EAWorld(eaworld)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部