DOM的缺陷有哪些?
- 牵一发而动全身(频繁操作DOM)
- 每次操作DOM,渲染引擎都需要进行重排、重绘或者合成等操作
- 对于 DOM 的不当操作还有可能引发强制同步布局和布局抖动的问题
- 大大降低渲染效率
虚拟 DOM 要解决哪些事情?
- 将页面改变的内容应用到虚拟 DOM 上,而不是直接应用到 DOM 上
- 虚拟 DOM 并不急着去渲染页面,而仅仅是调整虚拟DOM 的内部状态
- 在虚拟 DOM 收集到足够的改变时,再把这些变化一次性应用到真实的 DOM 上。
虚拟DOM执行流程是什么?
创建阶段:首先依据 JSX 和基础数据创建出来虚拟 DOM,它反映了真实的 DOM 树的结构。然后由虚拟 DOM 树创建出真实 DOM 树,真实的 DOM 树生成完后,再触发渲染流水线往屏幕输出页面。
更新阶段:如果数据发生了改变,那么就需要根据新的数据创建一个新的虚拟 DOM树;然后 React 比较两个树,找出变化的地方,并把变化的地方一次性更新到真实的DOM 树上;最后渲染引擎更新渲染流水线,并生成新的页面。
虚拟DOM都解决了哪些问题?
- 频繁更新DOM引起的性能问题
- 将真实DOM和js操作解耦,减少js操作dom复杂性。
虚拟DOM是如何解决这些缺陷的?
当有数据更新时,React 会生成一个新的虚拟 DOM,然后拿新的虚拟 DOM和之前的虚拟 DOM 进行比较(比较两个虚拟 DOM 的过程是在一个递归函数里执行的,其核心算法是 reconciliation),这个过程会找出变化的节点,然后再将变化的节点应用到DOM 上。通常情况下,这个比较过程执行得很快,不过当虚拟 DOM 比较复杂的时候,执行比较函数就有可能占据主线程比较久的时间,这样就会导致其他任务的等待,造成页面卡顿,这时,React 团队重写了reconciliation 算法,新的算法称为 Fiber reconciler,就是在执行算法的过程中出让主线程,这样就解决了 Stack reconciler 函数占用时间过久的问题。
虚拟DOM从双缓存和 MVC 角度又是怎样的?
双缓存是一种经典的思路,应用在很多场合,能解决页面无效刷新和闪屏的问题,虚拟 DOM 就是双缓存思想的一种体现。而基于 MVC 的设计思想也广泛地渗透到各种场合,并且基于 MVC 又衍生出了很多其他模式(如 MVP、MVVM 等),不过万变不离其宗,它们的基础骨架都是基于 MVC 而来,例如React,可以把它的虚拟DOM看成是MVC的视图部分,其控制器和模型都是由Redux 提供的。具体实现过程:
基于React、Redux构建的MVC模型:
-
控制器是用来监控 DOM 的变化,一旦 DOM 发生变化,控制器便会通知模型,让其更新数据
-
模型数据更新好之后,控制器会通知视图,告诉它模型的数据发生了变化;
-
视图接收到更新消息之后,会根据模型所提供的数据来生成新的虚拟 DOM;
-
新的虚拟 DOM 生成好之后,就需要与之前的虚拟 DOM 进行比较,找出变化的节点;
-
比较出变化的节点之后,React 将变化的虚拟节点应用到 DOM 上,这样就会触发 DOM节点的更新;
-
DOM 节点的变化又会触发后续一系列渲染流水线的变化,从而实现页面的更新。