CN115167854A - 一种虚拟文档对象模型树的处理方法及装置 - Google Patents
一种虚拟文档对象模型树的处理方法及装置 Download PDFInfo
- Publication number
- CN115167854A CN115167854A CN202210777654.XA CN202210777654A CN115167854A CN 115167854 A CN115167854 A CN 115167854A CN 202210777654 A CN202210777654 A CN 202210777654A CN 115167854 A CN115167854 A CN 115167854A
- Authority
- CN
- China
- Prior art keywords
- tree
- vdom
- node
- nodes
- pointer
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/30—Creation or generation of source code
- G06F8/38—Creation or generation of source code for implementing user interfaces
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/90—Details of database functions independent of the retrieved data types
- G06F16/95—Retrieval from the web
- G06F16/958—Organisation or management of web site content, e.g. publishing, maintaining pages or automatic linking
- G06F16/986—Document structures and storage, e.g. HTML extensions
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/30—Creation or generation of source code
- G06F8/31—Programming languages or programming paradigms
- G06F8/315—Object-oriented languages
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Databases & Information Systems (AREA)
- Data Mining & Analysis (AREA)
- Human Computer Interaction (AREA)
- Computing Systems (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本申请公开了一种虚拟文档对象模型树的处理方法及装置,该方法包括:在本地服务Native层创建第一虚拟文档对象模型VDom树;在进行页面发生重绘的情况下,重新生成第二VDom树,其中,第一VDom树和第二VDom树对应的数据保存在Native层;在Native层调用差分算法对第一VDom树和第二VDom树进行比较,其中,差分算法用于得到第二VDom树和第一VDom树之间的差别;根据第二VDom树和第一VDom树之间的差别调整渲染树。通过本申请解决了现有技术中VDom机制在应用层实现所导致的效率较低的问题,将VDom中部分数据结构和算法放在本地服务层,利用了Native层的运算优势,提高了VDom机制执行的效率,进而提高了页面显示的流畅度。
Description
技术领域
本申请涉及到网页页面渲染领域,具体而言,涉及一种虚拟文档对象模型树的处理方法及装置。
背景技术
文档对象模型(简称为Dom)一般被用在浏览器渲染上,浏览器渲染引擎工作流程大致分为5步,创建Dom树-创建风格规则(StyleRules)-创建渲染(Render)树-布局(Layout)-绘制(Painting),下面对这5步进行说明。
第一步,用HTML分析器,分析HTML元素,构建一颗Dom树。
第二步,用CSS分析器,分析CSS文件和元素上的样式,生成页面的样式表。
第三步,将Dom树和样式表,关联起来,构建一颗Render树。
第四步,有了Render树,浏览器开始布局,为每个Render树上的节点确定一个在显示屏上出现的精确坐标。
第五步,Render树和节点显示坐标都有了,就调用每个节点绘制方法,把它们绘制出来。
在上述过程中,浏览器会从构建Dom树开始从头到尾执行一遍流程,如果需要更新多个Dom节点,则会导致出现页面卡顿。例如,在一次操作中需要更新10个Dom节点,浏览器收到第一个Dom请求后并不知道还有9次更新操作,因此会马上执行流程,最终执行10次。在第一次计算更新完成之后,紧接着下一个Dom更新请求,这个节点的坐标值就变了,前一次更新为无用功,Dom节点坐标值等都是白白浪费的性能。因此,即使计算机硬件一直在迭代更新,操作Dom的代价仍旧是昂贵的,频繁操作还是会出现页面卡顿,影响用户体验。
为了解决这个问题,引入了虚拟文档对象模型(VirtualDOM,简称为VDom),引入该VDom树之后,对Dom的操作会首先反应在VDom上,在上述例子中,若一次操作中有10次更新Dom的动作,VDom不会立即操作Dom,而是将这10次更新的区别(diff)内容进行保存,最终一次性附着(attch)到Dom树上,再进行后续操作,避免大量无谓的计算量。这其中使用了Diff算法,Diff算法是一种差分算法用于对两个信息不同的VDom树进行差分计算。
在现有技术中,一般VDom的数据结构和Diff算法都在应用层(JS framework层,简称为JS层),在JS层使用的编程语言一般是JAVAScript,收到JS层编程语言的影响,VDom实现效率相对较低。
例如,在Weex框架中,通过利用Vue的虚拟节点(VNode)结构创建VDom结构,并在Vue框架中通过Diff算法计算差分操作集合,然后将Diff应用到渲染树中,由于VDom结构体和Diff算法在JS层实现,因此受JS语言效率影响效率低。又例如,在ReactNative框架中,与Weex类似,其利用React框架的VDom机制,整体实现机制在JS层,受JS语言效率影响效率低。
发明内容
本申请实施例提供了一种虚拟文档对象模型树的处理方法及装置,以至少解决现有技术中VDom机制在应用层实现所导致的效率较低的问题。
根据本申请的一个方面,提供了一种虚拟文档对象模型树的处理方法,包括:在本地服务Native层创建第一虚拟文档对象模型VDom树,其中,所述第一VDom树应用在页面绘制中;在所述页面发生重绘的情况下,重新生成第二VDom树,其中,所述第一VDom树和所述第二VDom树对应的数据保存在所述Native层;在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较,其中,所述差分算法用于得到所述第二VDom树和所述第一VDom树之间的差别;根据所述第二VDom树和所述第一VDom树之间的差别调整渲染树,其中,所述渲染树为绘制所述页面的依据。
根据本申请的另一个方面,还提供了一种虚拟文档对象模型树的处理装置,包括:虚拟文档对象模型VDom树构建模块,用于在本地服务Native层创建第一VDom树,其中,所述第一VDom树应用在页面绘制中;并且在所述页面发生重绘的情况下,重新生成第二VDom树,其中,所述第一VDom树和所述第二VDom树对应的数据保存在所述Native层;VDom树处理模块,用于在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较,其中,所述差分算法用于得到所述第二VDom树和所述第一VDom树之间的差别;并且根据所述第二VDom树和所述第一VDom树之间的差别调整渲染树,其中,所述渲染树为绘制所述页面的依据。
根据本申请的另一个方面,还提供了一种电子设备,包括存储器和处理器;其中,所述存储器用于存储一条或多条计算机指令,其中,所述一条或多条计算机指令被所述处理器执行以实现上述的方法步骤。
根据本申请的另一个方面,还提供了一种可读存储介质,其上存储有计算机指令,其中,该计算机指令被处理器执行时实现上述的方法步骤。
在本申请实施例中,采用了在本地服务Native层处理第一VDom树和第二VDom树,并在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较。通过本申请解决了现有技术中VDom机制在应用层实现所导致的效率较低的问题,将VDom中部分数据结构和算法放在本地服务(Native)层,利用了Native层的运算优势,提高了VDom机制执行的效率,进而提高了页面显示的流畅度。
附图说明
构成本申请的一部分的附图用来提供对本申请的进一步理解,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。在附图中:
图1是根据本申请实施例的JS层和Native层实现原理示意图;
图2是根据本申请实施例的构建VDom树的示意图;
图3是根据本申请实施例的Diff算法的流程示意图一;
图4是根据本申请实施例的Diff算法的流程示意图二;
图5是根据本申请实施例的Diff算法的流程示意图三;
图6是根据本申请实施例的首尾相同元素匹配的示意图一;
图7是根据本申请实施例的哈希匹配查找的示意图;
图8是根据本申请实施例的首尾相同元素匹配的示意图二;
图9是根据本申请实施例的未匹配到节点处理的示意图;
图10是根据本申请实施例的虚拟文档对象模型树的处理方法的流程图;
图11是根据本申请实施例的虚拟文档对象模型树的处理装置的流程图。
具体实施方式
需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互组合。下面将参考附图并结合实施例来详细说明本申请。
需要说明的是,在附图的流程图示出的步骤可以在诸如一组计算机可执行指令的计算机系统中执行,并且,虽然在流程图中示出了逻辑顺序,但是在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤。
在以下实施例中涉及到页面的重绘,下面对页面的重绘进行说明。正如在背景技术中提到的那样,Dom树一般被用在浏览器渲染上。浏览器在渲染一个页面的时候,从加载到完成,首先是构建Dom树,然后根据Dom节点的属性生成渲染树,当渲染树构建完成,页面就根据Dom树开始布局了,渲染树也根据设置的样式对应的渲染这些节点。在这个过程中,如果Dom树或者渲染树发生了变化,则页面需要重新渲染,该过程被称为页面的重绘。例如,删除一个Dom节点或者修改一个元素的宽高,这样就会导致页面的布局发生变化,Dom树的结构发生变化,引起Dom树的重构,重构完成之后就会导致渲染树的重新渲染,这个重新渲染的过程称为重绘。
VDom技术被大量应用到夸平台的小程序解决方案中,用来显示小程序的界面,这是因为VDom技术抹平了浏览器、PC、Mobile跨平台的用户界面(简称为UI)描述结构的差异,降低了用户的开发成本。除此之外,VDom还可以应用到网站或者应用(简称为APP)的页面渲染上,因此提高VDom的运行效率无论对于小程序还是对于网站或应用的页面显示的流畅度都起到了关键的作用。通过以下实施例的方案,可以加速VDom Diff算法,从而提高类似Vue这种框架在小程序、网站或应用中的效率和用户体验,在以下方案中,将现有技术在JS层实现的VDom的数据结构和Diff算法放在了Native层来实现,从而提高了VDom的执行效率。
首先对应用(JS Framework,简称为JS)层和本地服务(Native)层进行说明。一般在操作系统中均会存在应用层和本地服务层,其中,本地服务层通过C或者C++库为操作系统提供主要的特性支持;应用层这一层主要提供了构建应用程序时可能用到的各种应用程序编程接口(简称为API),开发者通过这一层的API构建自己的应用,应用层一般使用JAVAScript等语言来实现,应用层主要突出了编程的便利性,因此,其使用的编程语言更加便于使用,但是执行效率要低于本地服务层。
在本实施例中,将VDom机制中的部分操作移植到Naive层,从而可以提高VDom机制的运行效率。基于该原理,在本实施例中提供了一种虚拟文档对象模型树的处理方法,图10是根据本申请实施例的虚拟文档对象模型树的处理方法的流程图,如图10所示,该方法包括如下步骤:
步骤S102,在本地服务Native层创建第一虚拟文档对象模型VDom树,其中,第一VDom树应用在页面绘制中;
步骤S104,在进行该页面发生重绘的情况下,重新生成第二VDom树,其中,第一VDom树和第二VDom树对应的数据均保存在Native层;
步骤S106,在所Native层调用差分算法对第一VDom树和第二VDom树进行比较,其中,该差分算法用于得到第二VDom树和第一VDom树之间的差别;
步骤S108,根据第二VDom树和第一VDom树之间的差别调整渲染树,其中,渲染树为绘制上述页面的依据。
通过上述步骤是将原来在JS层实现的VDom树以及差分算法(即Diff算法)移植到Native层来实现,Native层使用的编程语言的效率要高于JS层,因此,通过上述步骤解决了现有技术中VDom机制在应用层实现所导致的效率较低的问题,将VDom中部分数据结构和算法放在本地服务(Native)层,利用了Native层的运算优势,提高了VDom机制执行的效率,进而提高了页面显示的流畅度。
图1是根据本申请实施例的JS层和Native层实现原理示意图,如图1所示,在Native层生成Dom,然后将CSS和布局与Dom进行关联,进而生成RenderTree,再根据RenderTree进行绘制从而进行用户界面的显示(Display)。使用VDom之后,在JS层发起渲染流程之后,创建VDom。在需要进行更新的情况下,通过调用Diff算法将更新后的VDom和之前的VDom进行差分比较并生成更新之后VDom,然后使用更新之后的VDom对Dom进行操作。在图1中,将原来在JS层生成的VDom以及在JS层进行的Diff算法均移植到到Native层来实现。将VDom移动到Native层之后,在本实施例中也可以将其称为Native VDom树。
在图1示出的场景涉及到生成VDom树以及对第一VDom树和第二VDom树之间的比较,生成VDom树之后将VDom对应的数据保存在Native层即可提高运行效率。对于用于比较第一VDom树和第二VDom树之间差别的Diff算法来说,可以将现有的Diff算法从JS层移植到Native层,在这种情况下,该Diff算法的效率也会提高。为了进一步提高运行效率,在本实施例中还提供一种可选的Diff算法,下面对使用该算法比较第一VDom树和第二VDom树进行说明。
在该可选方式中,可以对第一VDom树中的所有节点以及第二VDom树中的所有节点进行比较,得到第一VDom树和第二VDom树之间具有的相同的节点和不同的节点;然后,分别根据相同的节点和不同的节点调整渲染树中的元素。在这种实现方式中,可以按照第一VDom树和第二VDom树相同节点和不同的节点来调整渲染树中的元素,能够在一定程度上提高效率,例如,可以首先确定第二VDom树中与第一VDom树中相同的节点,根据相同的节点确定渲染树中的元素,然后再确定第二VDom树与第二VDom树中不同的节点,根据不同的节点生成渲染树中的元素,这样就可以完成整个渲染树的处理。
在该可选实施方式中,对于第二VDom树中与第一VDom树相同的节点,判断该相同节点在第一VDom树和第二VDom树中的位置是否相同,如果不相同,则根据该相同节点在第二VDom树中的位置调整该相同节点对应的元素在渲染树中的位置;对于第二VDom树中存在并且在第一VDom树中不存在的节点,根据该节点在第二VDom树中的位置将该节点对应元素移动到渲染树对应的位置上。
在渲染树中移动元素位置时,为了提高移动效率,渲染树可以通过链表保存元素,该链表通过链表首指针和链表尾指针确定元素在链表中的位置,这样通过链表首指针和链表尾指针就可以方便地在链表中移动并标识元素的位置。
对第一VDom树和第二VDom树所有的节点进行比较时,为了进一步提高比较效率,作为另一个可选实施方式,引入了首尾指针的方式来进行比较,在该方式中,可以首先比较第一VDom树和第二VDom树首尾的节点,然后依次移动首尾指针,直到完成所有节点的比较。下面对该可选的方式进行说明。
在该可选方式中,首先生成一组指针,其中,该组指针包括第一首指针、第一尾指针、第二首指针和第二尾指针,第一首指针用于指向第一VDom树所有节点中的首节点,第一尾指针用于指向第一VDom树所有节点中的尾节点,第二首指针用于指向第二VDom树所有节点中的首节点,第二尾指针用于指向第二VDom树所有节点中的尾节点;根据一组指针指向的节点查找第二VDom树和第一VDom树相同的节点;在存在相同的节点的情况下,根据查找到的相同节点在第二VDom树中的位置确定与该相同节点对应的元素在渲染树中的位置,并且将相同节点对应的指针向相邻节点移动;在指针移动之后继续根据移动后指针查找第二VDom树和第一VDom树中相同的节点。
比较的时候,可以采用将第二VDom树的首尾节点分别与第一VDom树的首尾节点首先进行比较,即将第二首指针指向的节点分别与第一首指针和第一尾指针指向的节点进行比较,确定是否相同;将第二尾指针指向的节点分别与第一首指针和第一尾指针指向的节点进行比较,确定是否相同。如果第二VDom树首尾节点与第一VDom树的首尾节点均不相同,此时可以在第一VDom树中的其他节点中查找与第二VDom树首尾节点相同的节点,查找方式可以使用哈希值的方式来查找。即在第二首指针或第二尾指针指向的节点与第一首指针和第一尾指针指向的节点均不相同的情况下,根据第二首指针或第二尾指针指向的节点的哈希值在第一VDom树中查找相同的节点。
通过上述对第二VDom树和第一VDom树节点进行查找之后,如果有在第二VDom树中存在并且在第一VDom树中不存在的节点,则可以根据该节点在第二VDom树中的位置生成渲染树的元素;同时,对于在第一VDom树中存在并且在第二VDom树中不存在的节点执行销毁操作,其中,销毁操用于在渲染树中移除该节点对应的元素。
上述差分算法运行在Native层并且使用了首尾指针来查找两个VDom树中相同与不同的节点,不但借助于Native层的特点提高了运行效率,还针对Diff算法进行了调整,使得运行效率得到了进一步提升。其中,在Native层运行Diff算法时可能会涉及到JS层函数的调用,为了解决调用问题,在一个可选实施方式中,可以采用Hook机制,即在Native层运行差分在Native层调用差分算法对第一VDom树和第二VDom树进行比较的过程中,获取差分算法中涉及到的钩子函数和/或指令函数,其中,钩子函数和/或指令函数为在应用JS层执行的函数;在调用差分算法对第一VDom树和第二VDom树比较完成之后,执行钩子函数和/或指令函数。
上述方案中通过在Naive层生成VDom树以及实现Diff算法以提高效率,上述这些方案可以在不同的框架内实现,例如,在Vue框架中,通过改造Vue框架机制,将渲染(render)和更新(update)两个流程与Native层相结合,将JS层的组件(Component)与虚拟节点(VNode)数据结构下沉到Native层实现,利用Native层的编程语言C或者C++(下文以C++为例进行说明)重新实现Diff算法完成VDom的差分计算,通过差分操作完成渲染树(RenderTree)的直接更新。
在Vue框架中,通过改造Vue render流程,创建Native VDom树(在下文中如果没有特别说明,VDom树均是指在Native层创建的Native VDom树)结构。然后在需要进行更新的时候,即update适当时机调用使用C++实现的Diff算法,对VDom新旧两颗树做差分算法。下面对Vue框架下的各个流程分别进行说明。以下涉及到的内容不仅仅可以应用到Vue框架中,也可以应用到其他框架中,下文仅仅是以Vue框架为例进行的说明。
1.Render流程
Render流程在JS组件渲染过程中发生,通过各种Render API完成VDom的创建。在本实施例中通过改造Render API,将原有在JS创建VDom结构的流程改为通过JSAPI在Native层创建对应VDom结构的流程。
在页面更新的时候,可以更新该页面某个组件,即更新可以以组件为单位,在该方式中,在创建完整的VDom树结构时,创建该完成的VDom树结构可以包括组件(Component)树以及VDom子树,其中,VDom树是将Component和VDom子树进行关联形成的。
创建该VDom树可以包括如下步骤:在Native层创建组件Component树;创建与该Component树对应的VDom子树;将VDom子树设置到所述Component树中的Component节点中,并通过建立所述Component与VDom子树之间的关联关系生成VDom树;其中,生成的VDom树的节点信息就被保存在了Native层。
图2是根据本申请实施例的构建VDom树的示意图,如图2所示,首先调用JS层的Component接口,通过Vue Component树结构,在Native层创建对应的Component树,可以称为Native Component树;通过Component的render流程,调用VDom接口,在Native层创建对应Component级别的VDom子树,可以称之为Native VDom子树,并设置到Native Component节点中。此时会获得两棵树,一棵Native Component树,另一棵为Native VDom子树,建立这两棵树的关联管理,并通过其关联关系获得一颗完整VDom树,可以称为Native VDom树。
在图2中创建的Native Component树以及Native VDom子树均是保存在Native层中,即其数据保存在Native层中。下面对创建VDom子树流程进行说明:在Render流程中通过递归创建子节点列表的机制,创建VDom子树,其中,VDom子树创建过程包括获取该书的节点基本信息,并将这些信息保存在Native层对应的VDom数据结构中。
在一个可选实施方式中,VDom树的数据结构可以包括如下部分:tag、data、styles、class、attrs、events、hooks、directives、children、text、vm以及key,其中,tag用于描述该节点类型,data用于描述该节点的各类属性值,styles和class分别用于指示动态、静态样式信息,attrs为属性值信息,events为事件信息,hooks为钩子信息,directives为指令信息,children用于描述该节点的子节点数组,text用于描述该节点的文本信息,vm用于描述该节点的上下文环境,key用于描述该节点的同级下的唯一键值。
上述VDom树保存在Native层中,因此其处理速度也会变快,提高了处理效率。
2.update流程
在Render流程中可以通过在Native层递归创建Component,以及其VDom子树,从而生成VDom树。在update流程中应用Diff算法来比较旧VDom树和新VDom树之间的差分,然后通过差分作用于RenderTree。
update流程在某个页面中的组件需要重绘时会被调用,即当页面某一Component发生重绘时,会更新该节点的VDom子树,通过Diff算法对比旧VDom树和新VDom树,产生差分操作集合作用于RenderTree中完成渲染结构的改变。
在Diff算法过程中所有涉及到JS空间的钩子函数、指令函数均后置处理,即在Diff算法完成后由update流程调度,这种处理方式被称为hook后置机制。
对于update流程中使用的diff算法可以有很多中实现方式,下面对一个可选的实现方式进行说明。
(1)在update流程的更新时机,将新VDom子树通过接口向Native层Component对象中请求更新。
(2)在Native Component更新接口中,通过VDom Patcher中的算法实现,进行Diff差分算法,并在Diff流程中将Diff操作应用到RenderTree中,其中,Patcher以及下文中的patch均是指在渲染时进需要对Diff算法中得到的差分部分进行渲染即可。
图3到图5是根据本申请实施例的Diff算法的流程示意图一到三,下面结合图3到图5对本实施例中的Diff算法进行说明。
如图3所示,如果旧VDom树为空,则进入图5示出的创建Element流程,在图5示出的流程中是依据新VDom树结构递归创建RenderTree。如果旧VDom树不为空,则递归查找每一层VDom及其子节点的差分,其中,为了描述方便将查找差分的过程简称为Diff。经过Diff之后判断新旧VDom树是否相同,如果新旧VDom树相同,则删除旧VDom树,然后进入创建Element流程中;如果新旧VDom树不相同,则启动更新Element流程,并且进入Patch子节点数组的流程,其中,Patch子节点数组的流程就是比较新旧VDom树子节点信息是否相同的流程,子节点信息保存在数组中,因此称为Patch子节点数组的流程。
在更新Element流程中,可以通过Hook机制,处理相关Element更新设置,包括样式、属性、事件、ref等。如果有其他后置hook,则标记,后续通过update流程处理。
图5示出了创建Element的流程,如图5所示,判断当前节点是否为Component,如果当前节点为Component,则标记hook后置,通过update流程继续创建Component;如果当前节点不是Component,则创建Element并插入到RenderTree中。这其中判断是否存在Hook,如果存在,则通过Hook机制,处理相关Element初始化设置,包括样式、属性、事件、ref等。如果有其他后置hook,则标记,后续通过update流程处理。
即对差分算法的运行会触发元素Element的创建或更新,其中,Element为RenderTree中的节点,在Element的创建或更新中,可以通过钩子(Hooks)机制,将Element的属性、样式、事件、ref(用于给元素注册引用信息)等特性应用到RenderTree中。在此过程中,update与Diff算法紧密配合,完成hook后置处理机制,支持自定义指令,自定义hooks等,其中,自定义指令、自定义hooks为Vue原有的机制,在此不再赘述。
在patch节点流程,当父节点是相同VDom时,则将新VDom中的差分信息更新到Render Tree中。判定是否为相同VDom方法可以有多种,例如,可以判断tag类型是否一致,key值是否一致等条件,如果这些条件均一致,则为相同的VDom树。
当父节点为Component节点时,更新Component信息到新VDom中;当父节点为非Component节点时,走更新Element流程。
当父节点是相同VDom时,同时比较其子节点数组信息,图4示出了Patch子节点数组的流程,在图4中会比较新旧VDom树的首尾节点是否相同,如果相同,则进行递归Patch节点流程。如果首尾节点不相同,则进行基于哈希的节点匹配,如果匹配到相同的节点,则进行递归Patch节点流程,如果没有匹配到相同的节点,则进行入创建Element流程。其中,递归Patch节点的流程是对下一个节点再次进行是否相同的判断并根据判断结果确定是否创建渲染树中的Element的流程。
下面对上述Patch流程中使用到的包含VDom数组Diff算法进行说明。在下述Diff算法中同时记录两组指针:第一组为VDom首尾指针,其中,旧VDom首尾节点的指针分别为:oldStartVDom、oldEndVDom,新VDom首尾节点的指针分别为newStartVDom、newEndVDom。第二组为Element首尾指针,其中,Element首尾指针分别为leftElm、rightElm,记录当前渲染树中有效的左右节点,初始值为null。
在该Diff算法中,首先根据首尾元素是否相同来来进行节点的匹配。比较oldStartVDom与newStartVDom是否为相同节点,如果是则走patch节点流程,记录leftElm为oldStartVDom对应的Element(若有);比较oldEndVDom与newEndVDom是否为相同节点,如果是则走patch节点流程,记录rightElm为oldEndVDom对应的Element(若有);比较oldStartVDom与newEndVDom是否为相同节点,如果是则走patch节点流程,并将oldStartVDom当前节点对应的Element从RenderTree链表中移到右侧(若有);记录rightElm为当前移动的这个Element元素(若有);比较oldEndVDom与newStartVDom是否为相同节点,如果是则走patch节点流程,并将oldEndVDom当前节点对应的Element从RenderTree链表中移到左侧(若有),记录leftElm为当前移动的这个Element元素(若有)。重复如上流程,如此往复完成首尾相同VDom的patch,首尾指针逐次向中间逼近。
当左右两侧未有相同VDom,则走哈希查找匹配流程,将oldStartVDom、oldEndVDom指针之间的所有VDom节点生成一张哈希表,VDom节点的key为其键值,在哈希表中查找与newStartVDom相同的VDom节点,如果有则走patch节点流程,并将该VDom节点对应的Element移到leftElm的右侧,并记录leftElm为当前移动的Element。
如果没有则走创建Element流程,递归创建newStartVDom,并将newStartVDom对应的Element标记在leftElem中。
完成Diff主要流程后,处理其他情况:如果还有新VDom节点未被创建,则递归创建并插入到leftElm右侧,如果有旧VDom节点未被匹配,则将这些节点Element做销毁操作,即从RenderTree中移除。
下面以图6到图9中的例子对上述Diff算法进行举例说明。图6是根据本申请实施例的首尾相同元素匹配的示意图一,如图6所示,旧VDom中的首节点PrevText与新VDom中的PrevText匹配成功,此时移动oldStartVnode到Text1(Empty),移动newStartVnode到Text1;旧VDom中的尾节点PostText与新VDom的尾节点匹配成功,此时移动oldEndVnode到Comp2,移动newEndeVnode到Comp2(Empty)。移动之后,再次进行首尾节点的匹配,此时,旧VDom中的Text1节点为空,与新VDom中的Text1节点无法匹配;新VDom中的Comp2为空,与旧VDom中的Comp2无法匹配。在这种情况下,将旧VDom的首节点Text1与新VDom的尾节点Comp2进行匹配,由于两者均为空,所以匹配成功。在匹配成功后,oldStartVnode移动到Comp1(Empty)节点,newEndVnode移动到Text2节点,如图7所示。
图7是根据本申请实施例的哈希匹配查找的示意图,在图7中,旧VDom和新VDom的首尾节点均不匹配,此时根据新VDom的Text1进行哈希匹配与旧VDom的Text2哈希匹配成功,将newStartVnode移动到Comp1,如图8所示。
图8是根据本申请实施例的首尾相同元素匹配的示意图二,如图8所示,按照首尾元素匹配的方式,查找到首尾相同的节点:新VDom中的Comp1和旧VDom中的Comp2,再次移动首尾指针,如图9所示,旧VDom中的首尾指针均移动到Comp1(Empty)节点,新VDom中的首尾指针均移动到Text2节点。
图9是根据本申请实施例的未匹配到节点处理的示意图,在图9中,新VDom中的Text2走创建Element流程,旧VDom中的Comp1被删除掉。
在上述流程中,在创建Element时,可以调用Hook模块,实现Vue中对应的Hook机制,例如,当节点有ref属性时,则将ref记录在页面级别的ref哈希表中;处理属性值更新操作,比如将旧VDom有的属性和新VDom没有的属性做删除操作;处理样式值更新操作,比如将旧VDom有的样式和新VDom没有的样式做删除操作;事件更新操作,做新旧VDom事件集合的增删改操作;自定义指令操作,如果当前VDom有自定义指令,则调度到JS层处理等,对于这些机制在本实施例中就不再一一赘述。
在本实施例中,提供一种电子装置,包括存储器和处理器,存储器中存储有计算机程序,处理器被设置为运行计算机程序以执行以上实施例中的方法。
上述程序可以运行在处理器中,或者也可以存储在存储器中(或称为计算机可读介质),计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
这些计算机程序也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤,对应与不同的步骤可以通过不同的模块来实现。
该本实施例中就提供了这样的一种装置或系统。该装置被称为虚拟文档对象模型树的处理装置,图11是根据本申请实施例的虚拟文档对象模型树的处理装置的流程图,如图11所示,该装置包括:VDom树构建模块12和VDom树处理模块14,下面对这两个模块进行说明。
虚拟文档对象模型VDom树构建模块12,用于在本地服务Native层创建第一VDom树,其中,所述第一VDom树应用在页面绘制中;并且在所述页面发生重绘的情况下,重新生成第二VDom树,其中,所述第一VDom树和所述第二VDom树对应的数据保存在所述Native层;VDom树处理模块14,用于在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较,其中,所述差分算法用于得到所述第二VDom树和所述第一VDom树之间的差别;并且根据所述第二VDom树和所述第一VDom树之间的差别调整渲染树,其中,所述渲染树为绘制所述页面的依据。
该系统或者装置用于实现上述的实施例中的方法的功能,该系统或者装置中的每个模块与方法中的每个步骤相对应,已经在方法中进行过说明的,在此不再赘述。
例如,所述VDom树构建模块12,用于在所述Native层创建组件Component树;创建与所述Component树对应的VDom子树;将所述VDom子树设置到所述Component树中的Component节点中,并通过建立所述Component与所述VDom子树之间的关联关系生成所述第一VDom树;其中,所述第一VDom树的节点信息保存在所述Native层。
又例如,所述VDom树处理模块14,用于对所述第一VDom树中的所有节点以及所述第二VDom树中的所有节点进行比较,得到所述第一VDom树和所述第二VDom树之间具有的相同的节点和不同的节点;根据所述相同的节点和不同的节点调整所述渲染树中的元素,其中,所述元素用于构成所述渲染树。
可选地,所述VDom树处理模块14,用于生成一组指针,其中,所述一组指针包括第一首指针、第一尾指针、第二首指针和第二尾指针,所述第一首指针用于指向所述第一VDom树所有节点中的首节点,所述第一尾指针用于指向所述第一VDom树所有节点中的尾节点,所述第二首指针用于指向所述第二VDom树所有节点中的首节点,所述第二尾指针用于指向所述第二VDom树所有节点中的尾节点;根据所述一组指针指向的节点查找所述第二VDom树和所述第一VDom树相同的节点;在存在相同的节点的情况下,根据查找到的相同节点在所述第二VDom树中的位置确定与所述相同节点对应的元素在所述渲染树中的位置,并且将相同节点对应的指针向相邻节点移动;在指针移动之后继续根据移动后指针查找所述第二树和所述第一VDom树中相同的节点。
可选地,所述VDom树处理模块14,用于将所述第二首指针指向的节点分别与所述第一首指针和所述第一尾指针指向的节点进行比较,确定是否相同;将所述第二尾指针指向的节点分别与所述第一首指针和所述第一尾指针指向的节点进行比较,确定是否相同;在所述第二首指针或所述第二尾指针指向的节点与所述第一首指针和所述第一尾指针指向的节点均不相同的情况下,根据所述第二首指针或所述第二尾指针指向的节点的哈希值在所述第一VDom树中查找相同的节点。
可选地,所述VDom树处理模块14,用于获取所述第二VDom树中存在并且在所述第一VDom树中不存在的节点;并根据该节点在所述第二VDom树中的位置生成所述渲染树的元素;将在所述第一VDom树中存在并且在所述第二VDom树中不存在的节点进行销毁操作,其中,所述销毁操用于在所述渲染树中移除该节点对应的元素;
可选地,所述VDom树处理模块14,用于对于所述第二VDom树中与所述第一VDom树相同的节点,根据该相同节点在所述第一VDom树和所述第二VDom树中的位置是否相同,如果不相同,则根据该相同节点在所述第二VDom树中的位置调整该相同节点对应的元素在所述渲染树中的位置;对于所述第二VDom树中存在并且在所述第一VDom树中不存在的节点,根据该节点在第二VDom树中的位置将该节点对应元素移动到所述渲染树对应的位置上。
在另一种实施方式中,所述装置还可以包括:函数处理模块,用于在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较的过程中,获取所述差分算法中涉及到的钩子函数和/或指令函数,其中,所述钩子函数和/或指令函数为在应用JS层执行的函数;在所述调用所述差分算法对所述第一VDom树和所述第二VDom树比较完成之后,执行所述钩子函数和/或指令函数。
通过上述实施例解决了现有技术中VDom机制在应用层实现所导致的效率较低的问题,将VDom中部分数据结构和算法放在Native层,利用了Native层的运算优势,提高了VDom机制执行的效率,进而提高了页面显示的流畅度。
以上仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。
Claims (13)
1.一种虚拟文档对象模型树的处理方法,包括:
在本地服务Native层创建第一虚拟文档对象模型VDom树,其中,所述第一VDom树应用在页面绘制中;
在所述页面发生重绘的情况下,重新生成第二VDom树,其中,所述第一VDom树和所述第二VDom树对应的数据保存在所述Native层;
在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较,其中,所述差分算法用于得到所述第二VDom树和所述第一VDom树之间的差别;
根据所述第二VDom树和所述第一VDom树之间的差别调整渲染树,其中,所述渲染树为绘制所述页面的依据。
2.根据权利要求1所述的方法,其中,在所述Native层创建所述第一VDom树包括:
在所述Native层创建组件Component树;
创建与所述Component树对应的VDom子树;
将所述VDom子树设置到所述Component树中的Component节点中,并通过建立所述Component与所述VDom子树之间的关联关系生成所述第一VDom树;其中,所述第一VDom树的节点信息保存在所述Native层。
3.根据权利要求1所述的方法,其中,在所述Native层调用所述差分算法对所述第一VDom树和所述第二VDom树进行比较,根据所述第一VDom树和所述第二VDom树之间的差别调整渲染树包括:
对所述第一VDom树中的所有节点以及所述第二VDom树中的所有节点进行比较,得到所述第一VDom树和所述第二VDom树之间具有的相同的节点和不同的节点;
根据所述相同的节点和不同的节点调整所述渲染树中的元素,其中,所述元素用于构成所述渲染树。
4.根据权利要求3所述的方法,其中,对所述第一VDom树和所述第二VDom树中的所有节点进行比较,并调整所述渲染树的元素包括:
生成一组指针,其中,所述一组指针包括第一首指针、第一尾指针、第二首指针和第二尾指针,所述第一首指针用于指向所述第一VDom树所有节点中的首节点,所述第一尾指针用于指向所述第一VDom树所有节点中的尾节点,所述第二首指针用于指向所述第二VDom树所有节点中的首节点,所述第二尾指针用于指向所述第二VDom树所有节点中的尾节点;
根据所述一组指针指向的节点查找所述第二VDom树和所述第一VDom树相同的节点;
在存在相同的节点的情况下,根据查找到的相同节点在所述第二VDom树中的位置确定与所述相同节点对应的元素在所述渲染树中的位置,并且将相同节点对应的指针向相邻节点移动;在指针移动之后继续根据移动后指针查找所述第二VDom树和所述第一VDom树中相同的节点。
5.根据权利要求4所述的方法,其中,根据所述一组指针指向的节点查找所述第二VDom树和所述第一VDom树相同的节点包括:
将所述第二首指针指向的节点分别与所述第一首指针和所述第一尾指针指向的节点进行比较,确定是否相同;
将所述第二尾指针指向的节点分别与所述第一首指针和所述第一尾指针指向的节点进行比较,确定是否相同;
在所述第二首指针或所述第二尾指针指向的节点与所述第一首指针和所述第一尾指针指向的节点均不相同的情况下,根据所述第二首指针或所述第二尾指针指向的节点的哈希值在所述第一VDom树中查找相同的节点。
6.根据权利要求4所述的方法,其中,对所述第一VDom树和所述第二VDom树中的所有节点进行比较,并调整所述渲染树的元素包括:
获取所述第二VDom树中存在并且在所述第一VDom树中不存在的节点;并根据该节点在所述第二VDom树中的位置生成所述渲染树的元素;
将在所述第一VDom树中存在并且在所述第二VDom树中不存在的节点进行销毁操作,其中,所述销毁操用于在所述渲染树中移除该节点对应的元素。
7.根据权利要求4至6中任一项所述的方法,其中,根据节点在所述第二VDom树中的位置调整所述渲染树的元素包括:
对于所述第二VDom树中与所述第一VDom树相同的节点,根据该相同节点在所述第一VDom树和所述第二VDom树中的位置是否相同,如果不相同,则根据该相同节点在所述第二VDom树中的位置调整该相同节点对应的元素在所述渲染树中的位置;
对于所述第二VDom树中存在并且在所述第一VDom树中不存在的节点,根据该节点在第二VDom树中的位置将该节点对应元素移动到所述渲染树对应的位置上。
8.根据权利要求7所述的方法,其中,所述渲染树通过链表保存元素,所述链表通过链表首指针和链表尾指针确定元素在所述链表中的位置。
9.根据权利要求1至6中任一项所述的方法,其中,还包括:
在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较的过程中,获取所述差分算法中涉及到的钩子函数和/或指令函数,其中,所述钩子函数和/或指令函数为在应用JS层执行的函数;
在所述调用所述差分算法对所述第一VDom树和所述第二VDom树比较完成之后,执行所述钩子函数和/或指令函数。
10.一种虚拟文档对象模型树的处理装置,包括:
虚拟文档对象模型VDom树构建模块,用于在本地服务Native层创建第一VDom树,其中,所述第一VDom树应用在页面绘制中;并且在所述页面发生重绘的情况下,重新生成第二VDom树,其中,所述第一VDom树和所述第二VDom树对应的数据保存在所述Native层;
VDom树处理模块,用于在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较,其中,所述差分算法用于得到所述第二VDom树和所述第一VDom树之间的差别;并且根据所述第二VDom树和所述第一VDom树之间的差别调整渲染树,其中,所述渲染树为绘制所述页面的依据。
11.根据权利要求10所述的装置,其中,在所述Native层创建所述第一VDom树包括:
所述VDom树构建模块,用于在所述Native层创建组件Component树;创建与所述Component树对应的VDom子树;将所述VDom子树设置到所述Component树中的Component节点中,并通过建立所述Component与所述VDom子树之间的关联关系生成所述第一VDom树;其中,所述第一VDom树的节点信息保存在所述Native层;
所述VDom树处理模块,用于对所述第一VDom树中的所有节点以及所述第二VDom树中的所有节点进行比较,得到所述第一VDom树和所述第二VDom树之间具有的相同的节点和不同的节点;根据所述相同的节点和不同的节点调整所述渲染树中的元素,其中,所述元素用于构成所述渲染树;
所述VDom树处理模块,用于生成一组指针,其中,所述一组指针包括第一首指针、第一尾指针、第二首指针和第二尾指针,所述第一首指针用于指向所述第一VDom树所有节点中的首节点,所述第一尾指针用于指向所述第一VDom树所有节点中的尾节点,所述第二首指针用于指向所述第二VDom树所有节点中的首节点,所述第二尾指针用于指向所述第二VDom树所有节点中的尾节点;根据所述一组指针指向的节点查找所述第二VDom树和所述第一VDom树相同的节点;在存在相同的节点的情况下,根据查找到的相同节点在所述第二VDom树中的位置确定与所述相同节点对应的元素在所述渲染树中的位置,并且将相同节点对应的指针向相邻节点移动;在指针移动之后继续根据移动后指针查找所述第二VDom树和所述第一VDom树中相同的节点;
所述VDom树处理模块,用于将所述第二首指针指向的节点分别与所述第一首指针和所述第一尾指针指向的节点进行比较,确定是否相同;将所述第二尾指针指向的节点分别与所述第一首指针和所述第一尾指针指向的节点进行比较,确定是否相同;在所述第二首指针或所述第二尾指针指向的节点与所述第一首指针和所述第一尾指针指向的节点均不相同的情况下,根据所述第二首指针或所述第二尾指针指向的节点的哈希值在所述第一VDom树中查找相同的节点;
所述VDom树处理模块,用于获取所述第二VDom树中存在并且在所述第一VDom树中不存在的节点;并根据该节点在所述第二VDom树中的位置生成所述渲染树的元素;将在所述第一VDom树中存在并且在所述第二VDom树中不存在的节点进行销毁操作,其中,所述销毁操用于在所述渲染树中移除该节点对应的元素;
所述VDom树处理模块,用于对于所述第二VDom树中与所述第一VDom树相同的节点,根据该相同节点在所述第一VDom树和所述第二VDom树中的位置是否相同,如果不相同,则根据该相同节点在所述第二VDom树中的位置调整该相同节点对应的元素在所述渲染树中的位置;对于所述第二VDom树中存在并且在所述第一VDom树中不存在的节点,根据该节点在第二VDom树中的位置将该节点对应元素移动到所述渲染树对应的位置上;
所述渲染树通过链表保存元素,所述链表通过链表首指针和链表尾指针确定元素在所述链表中的位置;
所述装置还包括:函数处理模块,用于在所述Native层调用差分算法对所述第一VDom树和所述第二VDom树进行比较的过程中,获取所述差分算法中涉及到的钩子函数和/或指令函数,其中,所述钩子函数和/或指令函数为在应用JS层执行的函数;在所述调用所述差分算法对所述第一VDom树和所述第二VDom树比较完成之后,执行所述钩子函数和/或指令函数。
12.一种电子设备,包括存储器和处理器;其中,所述存储器用于存储一条或多条计算机指令,其中,所述一条或多条计算机指令被所述处理器执行以实现权利要求1至9任一项所述的方法步骤。
13.一种可读存储介质,其上存储有计算机指令,其中,该计算机指令被处理器执行时实现权利要求1至9任一项所述的方法步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210777654.XA CN115167854A (zh) | 2022-07-04 | 2022-07-04 | 一种虚拟文档对象模型树的处理方法及装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210777654.XA CN115167854A (zh) | 2022-07-04 | 2022-07-04 | 一种虚拟文档对象模型树的处理方法及装置 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115167854A true CN115167854A (zh) | 2022-10-11 |
Family
ID=83490343
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210777654.XA Pending CN115167854A (zh) | 2022-07-04 | 2022-07-04 | 一种虚拟文档对象模型树的处理方法及装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115167854A (zh) |
-
2022
- 2022-07-04 CN CN202210777654.XA patent/CN115167854A/zh active Pending
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN108415702B (zh) | 一种移动终端应用界面动态渲染方法和装置 | |
US7917846B2 (en) | Web clip using anchoring | |
US20120110437A1 (en) | Style and layout caching of web content | |
JP2018517206A (ja) | アプリケーションページクイックアクセス | |
US9069829B2 (en) | Data items manager | |
CN108647025A (zh) | 文档对象模型中节点的处理方法及装置、电子和存储设备 | |
CN113126990B (zh) | 一种页面开发方法、装置、设备及存储介质 | |
US20050289450A1 (en) | User interface virtualization | |
CN112948039A (zh) | 页面显示方法、装置、设备及存储介质 | |
US20050108681A1 (en) | Method and system for applying user interface elements to data | |
CN113656119A (zh) | 一种通过dom节点回溯用户操作的方法及系统 | |
CN116560683A (zh) | 软件更新方法、装置、设备及存储介质 | |
CN115268879A (zh) | 代码处理方法、装置、电子设备及存储介质 | |
CN111124481A (zh) | 网页应用程序的安装包生成方法、装置、存储介质及设备 | |
CN113282799A (zh) | 节点的操作方法、装置、计算机设备和存储介质 | |
CN104461310B (zh) | 一种页面比对方法及系统 | |
CN111142990A (zh) | 一种微信小程序页面展示方法、装置、及存储介质 | |
CN115080114B (zh) | 应用程序的移植处理方法、装置和介质 | |
CN115167854A (zh) | 一种虚拟文档对象模型树的处理方法及装置 | |
CN112560403A (zh) | 文本的处理方法及装置、电子设备 | |
CN115185519A (zh) | 一种基于前端可视化的辅助编码方法 | |
CN115017161A (zh) | 一种结合虚拟dom更新树形数据结构方法、装置及应用 | |
CN112988278A (zh) | 资源文件的meta文件修改方法、装置、电子设备及存储介质 | |
CN117539491B (zh) | 页面布局方法、装置、电子设备、存储介质及程序产品 | |
CN117195840B (zh) | web编辑器中实时标注和插入异形对象的方法及装置 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |