DOM的缺陷
牵一发而动全身:js操作DOM影响到整个渲染流水线,对DOM的操作不当导致的强制同步布局和布局抖动问题等
虚拟DOM
- 创建阶段:根据JSX和基础数据创建虚拟DOM,根据虚拟DOM生成真实的DOM树后渲染,生成页面。
- 更新阶段:数据改变创建新的DOM树;然后 React 比较两个树,找出变化的地方,并把变化的地方一次性更新到真实的 DOM 树上;最后渲染引擎更新渲染流水线,并生成新的页面。
比较算法
比较两个虚拟 DOM 的过程是在一个递归函数里执行的,其核心算法是 reconciliation。当虚拟 DOM 比较复杂的时候,执行比较函数就有可能占据主线程比较久的时间,这样就会导致其他任务的等待,造成页面卡顿。
- React 团队重写了 reconciliation 算法,新的算法称为 Fiber reconciler, Fiber就是协程,在执行算法的过程中出让主线程,这样就解决了 Stack reconciler 函数占用时间过久的问题。
从双缓存视角看虚拟DOM
屏幕从前缓存区读取数据,但是往往页面中很多图形的操作涉及大量的计算,如果每次计算都写入缓存区,那么在显示一个稍微复杂点的图像时,页面可能会一部分一部分出来,在刷新页面时,会出现闪烁的情况。 若使用双缓存的话,可以将中间一部分的计算结果放到另一个缓存中,等全部计算结束,再把缓冲区的图形一次性复制到显示缓冲区,这样页面会较为稳定。 因此,这里可以将虚拟DOM看成DOM的一个Buffer,它会在完成一次完整的操作之后,在将结果应用到DOM上,这样可以减少一些不必要的更新,还能保证DOM的稳定输出。
从MVC模式视角看虚拟DOM
其核心思想就是将数据和视图分离,也就是说视图和模型之间是不允许直接通信的,它们之间的通信都是通过控制器来完成的。基于 MVC 又能衍生出很多其他的模式,如 MVP、MVVM 等,不过万变不离其宗,它们的基础骨架都是基于 MVC 而来。我们可以把 React 的部分看成是一个 MVC 中的视图: