「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。
通过JS操作DOM是会影响整个渲染流水线,操作不当还有可能引发强制同步布局和布局抖动的问题,这些操作都会大大降低渲染效率。尤其对于单页面应用,其DOM结构复杂,而且还需要不断的操作DOM树,每执行依次DOM操作都是非常耗时的,这就带来了真正的性能问题。于是我们需要一种减少DOM操作的方式,所以就有了虚拟DOM。
虚拟DOM要解决哪些问题
- 将页面的修改的内容应用到虚拟DOM上,虚拟DOM不会渲染页面,仅仅是调整虚拟DOM内部状态,这样操作虚拟DOM的代价就变得非常轻
- 当虚拟DOM收集到足够的改变时,再把这些变化一次应用到真实的DOM上
结合上图分析下虚拟DOM到底是怎么运行的。
- 创建阶段,首先根据JSX和基础数据创建出虚拟DOM,然后有虚拟DOM创建出真实DOM,然后再出发渲染流水线往屏幕输出页面
- 更新阶段,数据发生变化,根据需要更新的数据创建一个新的虚拟DOM,React比较两棵树,找出变化,把变化的地方一次性更新到真实的DOM树上,最后渲染引擎更新渲染流水线,并生成新的页面。
从双缓存和MVC模型两个视角理解虚拟DOM
双缓存
当图形操作很复杂且需要大量运算时,直接从前缓冲区读取数据,又可能看到的页面效果是一部分一部分显示的,会让用户感受到界面的闪烁。
使用双缓存,可以先将图形操作计算的中间结果存在另一个缓冲区,等全部的计算结束,再讲该缓存区的图形数据一次性复制到显示缓冲区,这样就使得输出的图像非常稳定。
虚拟DOM就是双缓存思想的一种体现。它会在完成一次完整的操作之后,再把结果应用到DOM上,这样就减少了不必要的更新,同时保证了DOM的稳定输出。
MVC模型
接下来看一下虚拟DOM在MVC模式中所扮演的角色。
MVC模式核心的思想就是把数据和视图分离,由模型Model,视图View和控制器Controller组成。
视图和模型之间是不允许直接通信的,它们直接的通信是通过控制器来完成。
通常情况下的通信路径是视图发生变化是,通知控制器,控制器再根据情况判断是否需要更新模型数据。当然还可以有不同的通信路径,根据不同的通信路径和控制器不同的实现方式,又出现了MVVM,MVP等其他模式。
虚拟DOM可以看成是MVC的视图部分。