什么是虚拟DOM

什么是虚拟DOM什么是虚拟 DOM virtualDOM 虚拟 DOM 用普通 js 对象来描述 DOM 结构 因为不是真实 DOM 所以称之为虚拟 DOM 虚拟 dom 是相对于浏览器所渲染出来的真实 dom 而言的 在 react vue 等技术出现之前 我们要改变页面展示的内容只能通过遍历查询 dom 树的方式找到需要修改的 dom 然后修改样式行为或者结构 来达到更新 ui 的目的 这种方式相当消耗计算资源 因为每次查询 dom 几乎都需要遍历整颗 dom 树 如果建立一个与 dom 树对应的虚拟 dom 对象 js 对象

什么是虚拟DOM?

virtual DOM 虚拟DOM,用普通js对象来描述DOM结构,因为不是真实DOM,所以称之为虚拟DOM。

虚拟 dom 是相对于浏览器所渲染出来的真实 dom而言的,在react,vue等技术出现之前,我们要改变页面展示的内容只能通过遍历查询 dom 树的方式找到需要修改的 dom 然后修改样式行为或者结构,来达到更新 ui 的目的。

这种方式相当消耗计算资源,因为每次查询 dom 几乎都需要遍历整颗 dom 树,如果建立一个与 dom 树对应的虚拟 dom 对象( js 对象),以对象嵌套的方式来表示 dom 树及其层级结构,那么每次 dom 的更改就变成了对 js 对象的属性的增删改查,这样一来查找 js 对象的属性变化要比查询 dom 树的性能开销小。

虚拟dom示例:

{ sel: 'div',// 表述标签,如p、sapn data: { }, children: undefined, text: 'virtual dom', //标签内的文本, ele: undefined, key: undefined } 

为什么要用虚拟DOM来描述真实的DOM呢?

创建真实DOM成本比较高,而如果用js对象来描述一个dom节点,成本比较低,另外我们在频繁操作dom是一种比较大的开销。所以建议用虚拟dom来描述真实dom。

这里有一些相关问题值得思考一下:

1.为什么操作真实DOM的成本比较高?

(1) dom 树的实现模块和 js 模块是分开的这些跨模块的通讯增加了成本

(2) dom 操作引起的浏览器的回流和重绘,使得性能开销巨大。

2.浏览器收到一个html页面是如何解析成页面呈现给用户的呢?

(1) 解析html:会按顺序解析。浏览器有专门的html解析器来解析HTML,并在解析的过程中构建DOM树

(2)构建dom树:它和步骤(1) 是同步进行,可以理解为边解析边构建。

(3)构建呈现树renderTree:将dom树与css结合,也就是将样式应用到dom节点上

(4)布局:计算呈现树节点的大小和位置,这一位置是递归进行的。

(5)绘制:布局完成后,便是将呈现树绘制出来显示在屏幕上。

这个具体的解析过程可参考:https://www.cnblogs.com/dojo-lzz/p/3983335.html

3.什么是回流和重绘?

  • 回流 reflow:当呈现树renderTree中的一部分或全部因为尺寸、布局、隐藏等改变改重新构建,称之为回流。
  • 重绘:当呈现树renderTree中的一部分元素需要更新属性,而属性只会影响外观、风格而不影响布局,比如颜色、字体大小等,则称之为重绘。

我们之前用jquery时基本都是在操作dom。会频繁引起呈现树的重绘和回流,pc端处理能力还不错,但移动端性能就会很差。导致页面卡顿

虚拟DOM的作用和类库

  • 虚拟DOM作用
    • 可以维护视图和状态之间的关系
    • 复杂视图情况下提升渲染性能
    • 虚拟DOM除了可以渲染成DOM节点,还可以渲染到其他平台如ssr(nuxt.js/next.js)、原生应用(weex/rn)、小程序等,增加了跨平台能力
  • 开源库
    • snabbdom
      • vue 2.x就是使用的snabbdom并进行了一定的改造
      • 代码量少
      • 可以通过模块进行扩展
      • 源码使用ts开发
    • virtual-dom

思考

通过以上的分析,你觉得虚拟DOM的性能一定高于常规DOM吗?

答案是不一定,如果是简单页面操作起来虚拟DOM未必会获胜,这个具体的原因我们后面会有章节再来分析。

那你觉得使用了虚拟DOM就真的不操作dom元素了吗?其实不是的,只是减少用户操作dom,虚拟DOM在渲染的时候其实还是会操作dom的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207184.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午2:23
下一篇 2026年3月19日 下午2:23


相关推荐

  • Ffmpeg进行视频文件转换

    Ffmpeg进行视频文件转换

    2021年9月1日
    78
  • 用DeepSeek+即梦一键生成ai图片!

    用DeepSeek+即梦一键生成ai图片!

    2026年3月12日
    3
  • java8时间新特性(localDate 和 Date 之间互转)

    java8时间新特性(localDate 和 Date 之间互转)时间日期相减java8新特性

    2022年10月3日
    5
  • web服务器有哪几种语言组合_服务器

    web服务器有哪几种语言组合_服务器  如今的Web服务器有很多种,大家在做项目的时候根据自己的需求进行灵活的选择。下面小编就给大家分享一下目前都有哪些Web服务器。  1.Apache  Apache也被叫做httpd服务器,是目前使用最广泛的web服务器,它被应用于各种平台之中。Apache刚开始被推出的时候有很多的缺陷,如今已经被修复的越来越完善,如果你是web服务器的钻研者,小编建议你一定要学习一下Apache的使用。  2.Nginx  Nginx是Linux平台下的优秀Web服务器,小编以前用过这个服务器,它…

    2026年1月27日
    5
  • JS数组合并(5种)

    JS数组合并(5种)前言项目过程中,经常会遇到JS数组合并的情况,时常为这个纠结。这里整理一下。简单而实用的for最容易想到的莫过于for了。会变更原数组,当然也可以写成生成新数组的形式。letarr=[1,2]letarr2=[3,4]for(letiinarr2){arr.push(arr2[i])}console.log(arr)//[1,2,3,4]arr.concat(arr2)会生成新的数组。letarr=[1,2]let

    2022年6月30日
    71
  • unity touch事件_安卓开发按钮点击事件

    unity touch事件_安卓开发按钮点击事件一:下面先说经常用的三个事件手指按下、手指移动、手指松开1.手指按下if(input.touchCount==1){if(input.touches[0].phase==TouchPhase.Beagn){//手指按下时,要触发的代码}​​​​​​​2.手指在屏幕上滑动if(input.touchCount==1)if(input.t

    2025年10月18日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号