虚拟DOM的比较

2024-06-20 10:28
文章标签 dom 虚拟 比较

本文主要是介绍虚拟DOM的比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

patch

将虚拟DOM渲染成DOM,这就是patch的作用

在vue运行的时候会生成新旧两个虚拟DOM树,通过比较这两棵DOM树,我们就能针对性的修改真实DOM
事实上,我们大可以在每次比较两棵DOM树的时候删除现有的DOM结构,然后根据新的虚拟DOM来渲染最新的DOM,但这样做的结果就是性能开销过大,所以vue并没有采取这种方式,vue会比对新旧两个vnode之间有哪些不同,然后根据对比结果找出需要更新的节点进行更新
我们知道DOM的操作对比JavaScript的操作来说是十分消耗性能的,因此我们完全可以将大部分的DOM操作放在JavaScript中,通过各种算法来得到需要更新的DOM节点,也就是通过虚拟DOM的比对,也就是patching算法

在patch中针对虚拟DOM的比对主要分为三部分

新增节点

首次渲染

新增节点最明显的一个应用场景就是首次渲染,因为首次渲染没有oldVNode,只有newVNode,当只有newVNode时patch会直接根据newVNode来生成视图

首次渲染

节点不同

除了首次渲染,当两个对应位置的VNode完全不同时,patch也会新增节点,用这个新节点来生成DOM以替换原来的旧节点

创建节点

事实上,只有三种节点会被插入到视图中,分别是元素节点,注释节点,文本节点

我们可以通过调用不同的创建函数来得到不同的节点,如果一个节点有子节点的话那么将会递归创建,创建子节点时,子节点的父节点就是当前刚创建出来的这个节点,所以子节点被创建后,会被插入到当前节点的下面,当所有子节点都创建并插入完毕后如果父节点已经被渲染到视图中,那么将子节点插入进去之后,会将所有节点都渲染到视图中

插入节点

patch会根据不同的节点使用不同的插入方式:

  1. 元素节点
    patch会调用当前环境下的appendChild方法将指定节点插入到指定父元素之下
  2. 文本节点
    patch会调用当前环境下的createTextNode方法
  3. 注释节点
    patch会调用当前环境下的createComment方法

删除节点

删除节点的场景很简单,即如果当前节点不在newVNode中,patch就会将它删除,具体过程是将新创建的DOM节点插入到旧节点的旁边,然后再将旧节点删除,从而完成替换过程

更新节点

静态节点

在更新节点之前,patch会判断当前节点是否是静态节点,如果是的话就跳过更新步骤

静态节点即渲染到视图上后永远不会改变的节点

<p>我是静态节点,我不需要发生变化</p>

文本节点

如果新旧两个VNode的文本不一致,则以newVNode为准调用setTextContent方法

元素节点

如果newVNode有children的话则会判断oldVNode有无children,如果没有则正常创建DOM,有的话则会通过diff来进行更加细致的比对
如果newVNode无children的话这说明这个新创建的节点是一个空节点,则在DOM中有什么删什么就行,达到视图中是空标签的目的

diff

我们通过循环newChildren来对比两个子节点列表,每从newChildren中取出一个VNode我们就去oldChildren中对比,如果匹配成功,则做更新操作,如果没有找到就做新增操作,如果两个节点的位置不同,则移动节点

插入子节点

diff通过循环newChildren,每次循环拿出一个节点来和oldChildren对比,如果是新增节点那么就会插入到所有未处理节点的前面

插入子节点

需要注意的是,我们插入子节点时的位置是在oldChildren中所有未处理节点前对应的位置,而不是oldChildren中所有已处理节点后对应的位置

因为我们是使用虚拟节点进行对比,而不是真实DOM节点做对比,插入的位置也是由两个节点列表对比得到,如果插入到已处理节点之后的话会导致顺序混乱

插入子节点

删除节点

删除子节点,本质上是删除那些oldChildren中存在但newChildren中不存在的节点

即当newChildren中的所有节点都被循环了一遍后,如果oldChildren中还有剩余的没有被处理的节点,那么这些节点就是需要删除的节点

更新节点

最后我们来更新节点,如果一个新旧两个节点位置相同且是同一个节点,那么直接进行更新节点操作,如果位置不一致的话我们还需要移动节点

移动节点

我们以newChildren为基准,将真实DOM中为同一节点的节点通过insertBefore方法移动到指定位置,那么问题来了,我们如何确定将节点移动到哪里呢

我们比对节点列表时是通过for循环遍历newChildren的,那么就意味着当前所遍历到的项的前面所有节点都是处理好的,我们只需要将指定的节点(真实DOM)插入到所有未处理节点之前(相对于oldChildren)就行

移动子节点

这篇关于虚拟DOM的比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1077873

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

VirtualBox中,虚拟系统文件VDI移动或者复制

在安装virtualbox以后有时需要复制,移动虚拟磁盘等操作,这些操作在vmware的虚拟机下面可以直接操作虚拟磁盘即可使用,但是在virtualbox环境 下每个VDI 文件都有一个唯一的uuid,而VirtualBox 不允许注册重复的uuid,所以直接复制的VDI文件是不能拿来使用的,我们就需要使用到virtualbox自带的管理命令来克隆一个VDI,这样通过命令克隆的VDI文件会重

比较学习难度:Adobe Illustrator、Photoshop和新兴在线设计平台

从入门设计开始,几乎没有人不知道 Adobe 公司两大设计软件:Adobe Illustrator和 Photoshop。虽然AI和PS很有名,有一定设计经验的设计师可以在早期探索和使用后大致了解AI和PS的区别,但似乎很少有人会系统地比较AI和PS。目前,设计软件功能多样,轻量级和网页设计软件已成为许多设计师的需求。对于初学者来说,一篇有针对性的AI和PS比较总结文章具有非常重要的指导意义。毕竟

JavaWeb系列二十: jQuery的DOM操作 下

jQuery的DOM操作 CSS-DOM操作多选框案例页面加载完毕触发方法作业布置jQuery获取选中复选框的值jQuery控制checkbox被选中jQuery控制(全选/全不选/反选)jQuery动态添加删除用户 CSS-DOM操作 获取和设置元素的样式属性: css()获取和设置元素透明度: opacity属性获取和设置元素高度, 宽度: height(), widt

Python几种建表方法运行时间的比较

建立一个表[0,1,2,3.......10n],下面几种方法都能实现,但是运行时间却截然不同哦 import time#方法一def test1(n):list=[]for i in range(n*10):list=list+[i]return list#方法二def test2(n):list=[]for i in range(n*10):list.append(i)#方法三d

Struts2与struts1与springmvc比较

最近做项目用到了struts2,之前一直是用struts1和springMVC。感觉到了struts2从很大程度上和这两个还是有很大区别的,所以今天搜集了些资料,给他们做一下对比。            Struts1官方已经停止更新,现在用的也比较少,这里主要讲一下struts2和struts1比较都有哪些不同和进步。Struts2可以说不是完全从struts1改进来的,因为

算法8—不通过比较,找出两个数的最大值

问题: 比如:给定两个值 5和10,不通过比较,直接找出最大值。 分析: 一旦涉及到不用比较找最大值,想都不用想,一般只能通过位运算来实现。  max = a - ((a-b)&((a-b)>>31)) 或者 max = ((a+b)+|a-b|)/2 如果找最小值,我们只需把两个值相加,减去max即可。

刷题——比较版本号

比较版本号_牛客题霸_牛客网 int compare(string version1, string version2){int len1 = version1.size();int len2 = version2.size();int i=0,j=0;while(i<len1 || j <len2){long num1 =0 ;while(i <len1 && version1.charAt

人工智能在数字病理切片虚拟染色以及染色标准化领域的研究进展|顶刊速递·24-06-23

小罗碎碎念 本期推文主题:人工智能在数字病理切片虚拟染色以及染色标准化领域的研究进展 这一期的推文是我发自内心觉得为数不多,特别宝贵的一篇推文,原因很简单——可参考的文献相对较少&方向非常具有研究意义&现在不卷。 数字病理方向的老师/同学应该清楚,不同中心提供的切片,染色方案是存在差异的,并且还存在各种质量问题,所以我们在数据预处理的时候,通常会先对切片的质量执行一遍筛选,然后再进行染

Java中的排序比较方式:自然排序和比较器排序

这里所说到的Java中的排序并不是指插入排序、希尔排序、归并排序等具体的排序算法。而是指执行这些排序算法时,比较两个对象“大小”的比较操作。我们很容易理解整型的 i>j 这样的比较方式,但当我们对多个对象进行排序时,如何比较两个对象的“大小”呢?这样的比较 stu1 > stu2 显然是不可能通过编译的。为了解决如何比较两个对象大小的问题,JDK提供了两个接口 java.lang.Comparab