Skip to content
New issue

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

Diff Algorithm #2

Open
remotesc2 opened this issue Jul 8, 2018 · 0 comments
Open

Diff Algorithm #2

remotesc2 opened this issue Jul 8, 2018 · 0 comments
Labels

Comments

@remotesc2
Copy link
Owner

假设1: DOM 节点跨层级的移动操作很少,忽略不计。
假设2: 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。
假设3: 对于同一个层级的一组子节点,可以通过它们唯一的ID来区分。

tree diff

只对树进行分层比较,两棵树只会对同一层次的节点进行比较。

React只会对相同层级的DOM节点进行比较,即同一个父节点下的所有子节点,当发现该节点已经不存在了,就会删除该节点和其所有子节点,不会再做进一步的比较。

而如果真的出现了跨层级的移动,并不会出现移动操作,而是被移动的跟节点被删除而后重新创建。

component diff

  1. 如果是同一类型的组件,按原策略继续比较 VirtualDOM 树即可
  2. 如果不是,则将该组件判断为 dirty component,从而替换整个组件下的所有子节点。
  3. 对于同一类型的组件,可能其 VirtualDOM 没有任何变化,如果能确切的知道这一点,那么就可以节省大量的 diff 运算时间。因此,React 允许用户通过 shouldComponentUpdate() 来判断是否需要对组件进行 diff 算法分析。

element diff

当节点属于同一层级时,diff 提供了 3 种节点操作,分别为 INSERT_MARKUP(插入),MOVE_EXISTING(移动),REMOVE_NODE(删除)。

  • INSERT_MARKUP: 新的组件类型不在旧集合中,即全新的节点,需要对新节点进行插入操作。
  • MOVE_EXISTING: 旧集合中有新组件类型,且 element 是可更新的类型,这时候就需要做移动操作,可以复用以前的 DOM 节点。
  • REMOVE_NODE: 旧组件类型,在新集合里也有,但对应的 element 不同则不能直接复用和更新,需要执行删除操作,或者旧组件不在新集合里的,也需要执行删除操作。
@remotesc2 remotesc2 added the react label Jul 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant