lotabout / ideas

log for new ideas and the execution of ideas
1 stars 0 forks source link

Learn how virtual-DOM works #3

Open lotabout opened 8 years ago

lotabout commented 8 years ago

Virtual DOM is used by react.js for updating the DOM quickly

Resources

lotabout commented 8 years ago

React 源码剖析系列 - 不可思议的 react diff

通过读上面的文章,首先对 React 中的核心价值有了一定的理解。

  1. 从使用者的角度,React 提供了动态更新的功能,从而将使用者从 Model -> View 间的关联解放出来。

    具体来说就是允许通过 JSX 绑定 View 中的元素与 Model 值的关联。这样使用者只要通过 setState 更新 Model 的值,React 便触发内部机制去更新相应的 Model。这样,使用者就不需要手工地去指定更新哪一个 View。

    这样方式的本质是 Observer 模式。所以在这方面的设计上并没有什么新鲜的内容。同时我认为 Angularjs 的绑定方式更加简单易懂,因为不需要显示调用 setState 之类的函数去触发 View 的更新。

  2. Virtual DOM + Diff 解决 Observer 模式的瓶颈

    使用 Observer 模式的一个问题是,当上游(Model)发生了一次修改时,下游(View)监测到了这个事件,如何定位到具体要修改的位置。因为修改 DOM 是很耗时的操作,而如果一棵很大的 DOM 树的源头对应的 Model 发生了修改,要去定位这棵树的哪些子节点需要修改,是十分困难的。通用的 Tree diff 操作需要 O(n^3),完全不可接受

    因此根据该文章所说,React 从三个方面去假设并优化了 Tree Diff 的操作,使之达到了 O(n) 的复杂度!具体如下:

    1. tree diff: 假设跨层的移动特别少见,所以采用逐层比较,若当前层发生了删除增加,则不再继续对比子节点。
    2. component diff: 以组件为单位,认为不同的组件几乎不会有相同的结果,因此若是节点的组件类型发生变化,则不再继续对比子节点。
    3. element diff: 本质上是一个 Edit Distance 的问题,标准方法是用动态规划,需要 O(mn) 的时间/空间复杂度。但 virtual DOM 并不需要准确解,因此它的解法是一个变种。方法的思想比较简单,之后上图。