虚拟DOM和diff
一.基本了解
1》vdom是实现vue和react的重要基石
2》diff算法是vdom中最核心,最关键的部分
二.背景:
三.上述问题的解决方案:利用vdom
DOM操作非常耗费性能,为了极大程度减少DOM渲染的范围,我们通过JS虚拟DOM节点,进行计算,找出最小的更新范围去更新,这个对比过程就是diff算法。
四.用JS模拟dom结构:
为什么这么写,后面会说
五.什么是diff算法:(对比算法)
上述树的diff算法时间复杂度 o(n的三次方)
优化时间复杂度到o(n)
六snabbdom源码解读:
snabbdom源码
h(模拟dom节点)
patch(container,vnode)//container是真实DOM节点,vnode是虚拟对象
patch(vnode,newVnode) //
是snabbdom主要的API
Vnode() 类( vnode就是 js模拟的dom节点)
Vnode 是虚拟 DOM 节点类,其实例 vnode 是一个包含着渲染 DOM 节点所需要的一切信息的普通对象。
children 和 text 是互斥的,不会同时存在。
如果要我们自己实现一个虚拟dom,大概过程应该有一下三步:
1.compile,如何把真实DOM编译成vnode。
2.diff,我们要如何知道oldVnode和newVnode之间有什么变化。
3.patch, 如果把这些变化用打补丁的方式更新到真实dom上去。
1》var vnode=h()
调用h函数 我们查看源代码的src文件夹里面的h.ts
中间过程不用管,发现返回一个vnode()
再进入vnode.ts中:
发现vnode()函数返回的是一个对象
结果就是h()函数返回一个对象
2》看patch:
调用了init函数,我们去init.ts里面去找,发现return一个patch函数
供下面的patch函数调用
上述处理方式,跟diff算法优化方式相同
3》上面可知当key和sel相同时,执行sameVnode(),这个函数里面执行
patchVnode(),我们来了解一下patchVnode()如何对比的:主要是新旧text和children的判断
4》
在上述patchVnode()运行过程中,若新旧ch都有的话,会进行对比函数
updateChildren(),我们讲一下updateChildren()
在对比过程中,idx指针会慢慢靠拢移动,当移动到中间位置,两者相等,循环结束
不设key,newCh和oldCh只会进行头尾两端的相互比较,设key后,除了头尾两端的比较外,还会从用key生成的对象oldKeyToIdx中查找匹配的节点,所以为节点设置key可以更高效的利用dom。