再谈 Virtual DOM(四)
Virtual DOM
典型 VirtualDOM
典型的 virtual-dom 主要包含以下步骤:
createElement
创建VNode
,并通过children
关联生成一个VTree
render
将组件渲染成VirtualDOM
- 首次渲染,调用
document.createElement
创建RealDOM
- 二次渲染
render
生成第二棵VirtualDOM 2
diff
计算两棵VirtualDOM 1
和VirtualDOM 2
的差异patch
将差异 批量 应用到RealDOM
- 首次渲染,调用
缺点:
- 运行内存占用较多,并有两颗 VirtualDOM 树
- https://auth0.com/blog/face-off-virtual-dom-vs-incremental-dom-vs-glimmer/
- https://teropa.info/blog/2015/03/02/change-and-its-detection-in-javascript-frameworks.html
Preact
createElement
创建VNode
,并通过children
关联生成一个VTree
render
将组件渲染成VirtualDOM
- 首次渲染,调用
document.createElement
创建RealDOM
- 二次渲染
render
第二次生成VirtualDOM
(注意:此处是第二次,不是第二棵)build
计算RealDOM
和VirtualDOM
的差异并依次更新(注意:此处是依次更新,不是批量更新)
- 首次渲染,调用
优点:
- 策略简单,内存占用少
React
批量更新使用 Fiber 优化,将原有的递归不可中断更新,变成循环可中断更新。
- https://github.com/maoxiaoxing/react-study/tree/master/Fiber
- https://juejin.cn/post/6993973502852202503
- https://github.com/acdlite/react-fiber-architecture
Diff 算法
典型 XML Diff
一个典型的 Diff 算法复杂度为 O(n^3)
- https://github.com/acdlite/react-fiber-architecture
- https://legacy.reactjs.org/docs/reconciliation.html
- https://github.com/facebook/react/issues/6170
- A Survey on Tree Edit Distance and Related Problems
RTED
RTED requires O(n2) space as the most space-efficient competitors, and its runtime complexity of O(n3) in the worst case is optimal.
权衡
React 引入 VirtualDOM 及其出现,另外一个主要原因是 React Native 的存在。
由于 VirtualDOM 的存在,使得 React UI 描述成为一种更为通用的存在,比如:NodeJS、Web、iOS、Android、PC Native 等等,可以做到 Learn once, write anywhere.
这是【跨端需求、多端开发效率】与【单端性能、单端开发效率】之间平衡,并没有绝对的优劣,正如 VirtualDOM 的一棵树和二棵树的区别,也是一种平衡。
Note that a virtual DOM is pure overhead if you already have a real DOM to work with.
https://news.ycombinator.com/item?id=34616031
For some reason I thought the virtual DOM was a native feature of the browser https://news.ycombinator.com/item?id=34633339
React 带来了什么?
The big improvements that React brought to the mainstream were componentization, and popularizing declarative rendering. https://news.ycombinator.com/item?id=34621279
个人认为 React 最大的改进就是:组件化。而在当下,Universal Component 已成为标准 WebComponent.
其他工作
- Rax 与 VirtualDOM
- Flutter
- 鸿蒙
References
- https://news.ycombinator.com/item?id=34612162
- https://svelte.dev/blog/virtual-dom-is-pure-overhead
- https://github.com/mbasso/asm-dom
- https://github.com/patrick-steele-idem/morphdom
- https://zhoukekestar.github.io/notes/2017/08/07/webcomponents-demo.html
- https://zhoukekestar.github.io/notes/2017/08/07/beyond-framework.html
- https://github.com/WebReflection/hyperHTML
-
https://github.com/AFASSoftware/maquette
- https://en.wikipedia.org/wiki/Virtual_DOM
- https://svelte.dev/blog/virtual-dom-is-pure-overhead
- https://auth0.com/blog/face-off-virtual-dom-vs-incremental-dom-vs-glimmer/
- RTED: A Robust Algorithm for the Tree Edit Distance
- Minimal Edit-Based Diffs for Large Trees
- Detecting Changes in XML Documents
- Google String diff-match-patch