8.5 diff 算法优化

前面有个分支,当四种比较节点都找不到匹配时,会调用findIdxInOld找到旧节点中和新的比较节点一致的节点。节点搜索在数量级较大时是缓慢的。查看Vue的源码,发现它在这一个环节做了优化,也就是我们经常在编写列表时被要求加入的唯一属性key,有了这个唯一的标志位,我们可以对旧节点建立简单的字典查询,只要有key值便可以方便的搜索到符合要求的旧节点。修改代码:

  1. class Vn {
  2. updateChildren() {
  3. ···
  4. } else {
  5. // 都不符合的处理,查找新节点中与对比旧节点相同的vnode
  6. if (!oldKeyToId) oldKeyToId = this.createKeyMap(oldCh, oldStartIndex, oldEndIndex);
  7. idxInOld = util._isDef(newStartVnode.key) ? oldKeyToId[newStartVnode.key] : this.findIdxInOld(newStartVnode, oldCh, oldStartIndex, oldEndIndex);
  8. // 后续操作
  9. }
  10. }
  11. // 建立字典
  12. createKeyMap(oldCh, start, old) {
  13. const map = {};
  14. for(let i = start; i < old; i++) {
  15. if(oldCh.key) map[key] = i;
  16. }
  17. return map;
  18. }
  19. }