# 9. diff算法原理
- 先同级比较,再比较子节点
- 先判断一方有子节点一方没子节点的状况(新增和删除子节点)
- 比较都有子节点的情况
- 递归比较子节点
function sameVnode (a, b) {
return (
a.key === b.key && (
(
a.tag === b.tag &&
a.isComment === b.isComment &&
isDef(a.data) === isDef(b.data) &&
sameInputType(a, b)
)
)
)
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
判断 sameNode 的时候,只会判断key
、 tag
、是否有data的存在(不关心内部具体的值)
、是否是注释节点
、是否是相同的input type
,来判断是否可以复用这个节点。
然后把旧的 vnode
和 新的 vnode
进行 patchVnode
操作。
在进行 patchVnode 的时候,会去检查 props 有没有变更,如果有的话去更新这个响应式的值,触发 dep.notify
,触发子组件视图的重新渲染等一套很重的逻辑。
然后,还会额外的触发以下几个钩子,假设我们的组件上定义了一些dom的属性或者类名、样式、指令,那么都会被全量的更新。
updateAttrs
updateClass
updateDOMListeners
updateDOMProps
updateStyle
updateDirectives
1
2
3
4
5
6
2
3
4
5
6
而这些所有重量级的操作,都可以通过直接复用 相同数据的vnode 来避免,是因为我们偷懒写了 index 作为 key,而导致所有的优化失效了。
https://juejin.im/post/5e8694b75188257372503722 (opens new window)