We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在对比子节点差异的时候,我们需要区分新旧子节点的不同情况:
这8中情况,都非常简单,就不过多论述了。
再先看一下,我们之前是怎么操作新旧节点均为多个子节点的情况的:
遍历旧的子节点,将其全部移除:
for (let i = 0; i < prevChildren.length; i++) { removeChild(container,prevChildren[i].el) }
遍历新的子节点,将其全部挂载
for (let i = 0; i < nextChildren.length; i++) { mount(nextChildren[i], container) }
在浏览器中操作DOM是极为昂贵的,这种操作方式需要不停的对DOM进行删除和创建的操作,但是对于新旧节点差异很小的情况下,无法尽可能的复用原有DOM节点,从而造成性能上的浪费。
看一个简单的例子:
按照之前的逻辑,原有子节点删除,重新创建所有的新子节点,无疑会造成性能上的巨大浪费。
我们真正想做的,其实是找出二者之间的区别,针对二者的不同进行修改。
找出新旧子节点的不同,并针对不同之处进行更新的过程,其实就是我们常说的核心Diff算法。
Vue对于Key的说明:
key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。
React对于Key的说明:
当子元素拥有 key 时,React 使用 key 来匹配原有树上的子元素以及最新树上的子元素。
总结
新子节点根据自己的key找到对应的旧子节点。
通过key来查找新旧子节点的对应关系其实很好理解,但不论是React还是Vue,都支持不传递Key的使用方式,那么这种方式,新旧子节点如何查找对应关系的呢?
在没有key的时候,为了能够复用原有的dom,所以我们需要通过新旧子节点的顺序来进行比对。
当新旧子节点长度相同时:
当新子节点长度大于旧子节点长度:
当新子节点长度小于旧子节点长度:
简单代码:
const noKeyDiff = function(prevChildren,nextChildren,container){ //旧长度 let prevLen = prevChildren.length; //新长度 let nextLen = nextChildren.length; //最小长度 let commonLen = Math.min(prevLen,nextLen); //长度相同 for(let i = 0;i<commonLen;i++){ patch(prevChildren[i],nextChildren[i],container) } //新长大于旧长,挂载 if(nextLen > prevLen){ for(let i = commonLen; i<nextLen; i++){ mount(nextChildren[i],container); } } //新长小于旧长,删除 else if(prevLen > nextLen){ for(let i = commonLen; i<prevLen; i++){ removeChild(container,prevChildren[i].el) } } }
对于简单DOM的情况,性能更好~
因为至于一次循环,就处理了所有的新旧子节点,当key存在的时候,无论使用何种diff优化算法,都不可避免的需要进行多重循环来进行key的比对。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
虚拟DOM之更新子节点(一)
回顾
在对比子节点差异的时候,我们需要区分新旧子节点的不同情况:
这8中情况,都非常简单,就不过多论述了。
再先看一下,我们之前是怎么操作新旧节点均为多个子节点的情况的:
遍历旧的子节点,将其全部移除:
遍历新的子节点,将其全部挂载
在浏览器中操作DOM是极为昂贵的,这种操作方式需要不停的对DOM进行删除和创建的操作,但是对于新旧节点差异很小的情况下,无法尽可能的复用原有DOM节点,从而造成性能上的浪费。
看一个简单的例子:
按照之前的逻辑,原有子节点删除,重新创建所有的新子节点,无疑会造成性能上的巨大浪费。
我们真正想做的,其实是找出二者之间的区别,针对二者的不同进行修改。
找出新旧子节点的不同,并针对不同之处进行更新的过程,其实就是我们常说的核心Diff算法。
React/Vue中的key
Vue对于Key的说明:
React对于Key的说明:
总结
通过key来查找新旧子节点的对应关系其实很好理解,但不论是React还是Vue,都支持不传递Key的使用方式,那么这种方式,新旧子节点如何查找对应关系的呢?
无Key的Diff
在没有key的时候,为了能够复用原有的dom,所以我们需要通过新旧子节点的顺序来进行比对。
当新旧子节点长度相同时:
当新子节点长度大于旧子节点长度:
当新子节点长度小于旧子节点长度:
简单代码:
无key的好处
因为至于一次循环,就处理了所有的新旧子节点,当key存在的时候,无论使用何种diff优化算法,都不可避免的需要进行多重循环来进行key的比对。
The text was updated successfully, but these errors were encountered: