前端渲染性能优化及其应用
2022-07-19倪新勇
倪新勇
(南京邮电大学,江苏 南京 210000)
常规而言,想要针对应用进行优化,一般会考虑到从硬件和软件两个方面实现提升。如果是针对硬件,常规的优化方案主要包括扩大带宽、服务集群等部署后端应用方式,而这些性能的提升都是依靠大量的硬件资金投入,购入相应的硬件设备以此提升处理数据的性能。而如果是针对软件进行优化,基本是软件编码流程优化或者算法提升软件的处理性能,此相对比之下,从软件的方向进行技术优化实现应用的性能提升更加具有实际意义。本文选定应用软件编码中的前端方向,通过虚拟DOM 技术,研究针对应用中的Web 界面的前端优化。
1 浏览器渲染机制
若要针对前端性能进行优化,首先要了解整个应用页面的渲染流程。而想要了解页面的渲染过程,浏览器渲染性能是必须要掌握的核心内容。浏览器是通过解析器负责对语法的解析,依据解析后的内容渲染整个网页。
浏览器进行渲染的前提条件是浏览器在与用户的功能交互过程中产生了网络请求,之后向服务器端发送数据和请求对应需要的资源,完成此步骤后,需要完成的就是把从服务器中请求的资源渲染到页面中对应的位置处。
1.1 浏览器渲染过程
浏览器把服务器端请求到的数据渲染成为应用页面的整个过程是十分迅速的,其流程如下。
第一步,借助HTML 解析器,对数据中的HTML 元素节点解析之后以此构建出DOM 树。
第二步,借助CSS 解析器,对数据中CSS 样式文件包含的元素样式和元素内连样式进行解析并构建CSSOM 树,也就是应用页面的元素样式表。
第三步,将DOM 树和CSSOM 树放在一起,根据节点结合构建渲染树。其中的每个DOM 节点都含有挂载方法,对应各自节点的样式信息。
第四步,渲染树构建完,根据渲染树中记录的信息,浏览器开始调用layout(布局),为渲染树上的每一个节点确定其在显示页面中出现的坐标位置。
第五步,在渲染树上的节点的显示坐标全部确定之后,接下来浏览器就会就调用每个节点paint(绘制)方法,将它们按照之前完成的样式表和坐标位置一一对应后绘制出来显示在页面上。页面渲染流程如图1 所示。
图1 页面渲染流程图
浏览器构建DOM 树并渲染页面的整个流程是一个循环渐进过程,并不是线性接力过程,这些过程在浏览器的流程不是完全独立的,而是会有某个过程和时间点的交叉。
1.2 浏览器渲染机制的问题
除了上述的浏览器页面渲染流程之外,还有两个经常会触发且会对浏览器的渲染性能产生影响的操作:
(1)回流。当页面上某些元素节点位置信息发生变化时,浏览器会因为这些改动而重新从最底层开始计算该节点的位置,验证并计算渲染树。
(2)重绘。当页面上某些元素节点样式信息发生变化时(这些元素变化时不影响整个页面的位置信息布局),浏览器会因为这些改动重新记录节点的元素样式,并更新渲染树,进行重画操作。
这两个操作都是在原本的页面内容渲染好之后又发生了资源的变动时,触发的浏览器渲染机制对页面的部分内容重新渲染,他们之间的区别主要是在于对页面的整体布局是否产生影响。在实际应用的页面中,这两种操作都会对页面的渲染性能产生影响,降低页面加载速率,但是这两种机制的出现在页面的正常使用过程中是不可避免的,是属于功能交互所带来的额外耗费。但是如果在一个页面功能多且繁杂的应用中,频繁地触发回流和重绘,则会给浏览器的渲染引擎带来工作量和性能耗费。
当页面频繁地刷新或者出现用户页面交互产生的回流和重绘时,会出现很多需要处理和渲染的数据致使浏览器产生大量的DOM 操作,而一段时间过多的DOM操作需要浏览器频繁的执行渲染流程,这不仅会占用浏览器很大的硬件性能,甚至会影响到重新渲染显示页面速度,从而对应用的响应速度产生不好的影响,尤其是多次变动导致的页面重新渲染带来的耗费。
2 虚拟DOM 技术
依据浏览器渲染流程,以及元素变动时带来的额外渲染流程对性能耗费问题,只要能够减少页面中DOM操作的频率,就可以实现对应用性能的优化。而减少DOM 操作的频率,就要在一定时间内,把这些DOM 操作一起挂载到页面中。可以利用JavaScript 模拟出一整个应用页面中所有元素节点,从而构造出一棵依据DOM 树中节点信息模仿而来的虚拟DOM 树。而页面中多次改动的变动信息由JavaScript 记录之后,再让浏览器根据这些节点的变动信息而对页面进行一次性渲染。由JavaScript 模拟构建虚拟DOM 树,根据页面的变动,得出页面变动前后的差异,再渲染出页面,这就是虚拟DOM 技术。
假设应用页面中的变动中是五十个节点发生位置信息的变动,按照之前介绍的常规的浏览器渲染流程,每存在一次DOM 操作,浏览器都将对整个页面进行一遍绘制,总共要进行五十次的页面绘制,这对浏览器的性能耗费是十分巨大的。而采用虚拟DOM 技术,并不会短时间内立即执行那么多次的DOM 操作,而是将某段时间内五十次更新操作中的变动信息保存到本地JavaScript 对象中,之后依据这个JavaScript 对象将五十次更新信息一次性挂载到DOM 树上,浏览器额外绘制一次页面就完成了如此多的内容更新。
使用虚拟DOM 技术相比于直接进行DOM 操作具有很多优势,包括:虚拟DOM 技术使用JavaScript 为主,而不需要额外其他生产环境作为编译支撑,且因为JavaScript 编写的,有跨平台能力;由于JavaScript 的执行速度相对较快,虚拟DOM 通过多次操作JavaScript 记录页面变动减少了直接操作DOM 的次数,所以虚拟DOM显著地提高了页面渲染效率。
2.1 虚拟DOM 技术实现原理
一个应用页面一般由很多个元素节点组合嵌套构成基本骨架,某一个元素节点的改变可能会导致附近有所联系的节点也会产生连锁变化。应用页面包含的内容信息量越大,这种关联变化就会产生越大的影响。如果频繁地进行DOM 操作修改页面布局,会使应用页面出现明显的卡顿,而使用虚拟DOM 可以直接减少修改页面产生的DOM 操作的次数,提升流畅度。
虚拟DOM 树是根据真实DOM 树模仿出来的,它们两个是节点一一对应的同种树状数据结构,同时每个节点也都会包含相应全部属性,而这些节点的属性,不管在真正DOM 树中的节点属性还是在虚拟DOM 树中的节点属性都是一样的,这是使用JavaScript 是对DOM 树的一种抽象模仿表示。页面中更新产生的所有的DOM 操作都会提前在虚拟DOM 上执行,这样会产生对应新的页面的DOM 结构的新虚拟DOM 树。新旧两棵虚拟DOM 树进行对比,得出差异点,之后浏览器根据这个差异点定位到实际需要更新的节点,在页面中进行局部渲染。
2.2 虚拟DOM 技术的实现流程
步骤一:在最先首次页面加载显示时,根据真实DOM 结构,使用JavaScript 模拟其结构并构建出对应的虚拟DOM 树,之后根据DOM 树渲染成应用展示页面。
步骤二:变动产生后,根据新的改动后的结构使用JavaScript 模拟出新虚拟DOM 树,并且和步骤一中形成的旧的虚拟DOM 树进行比较,新旧虚拟DOM 树的区别就是需要计算出并且记录的差异对象。
步骤三:记录步骤二中所记录的差异对象,之后应用到步骤一中的真正DOM 树上,让浏览器进行页面的重新渲染以此实现页面的内容更新。
2.2.1 模拟虚拟DOM 树
要对以上的三个步骤进行实现,完成实现虚拟DOM技术的应用,首先要用JavaScript 模拟表示页面中DOM结构。借助JavaScript 对象,涵盖节点中应该有的属性就可以很方便地表示DOM 节点。通过JavaScript 对象的属性表达记录这些节点信息。这个过程中构建真正DOM树,并且也构建出了虚拟DOM 树,这棵虚拟DOM 树与真正的DOM 树包含的信息都是一样的。
2.2.2 对比新旧虚拟DOM 树
当页面中的数据发生改动,产生了改变页面结构的变动时,先通过JavaScript 模拟出最新页面的虚拟DOM树,然后新旧虚拟DOM 进行对比,得到页面中变动节点的信息。
在正常页面中的真实DOM 树结构会很复杂,而根据其模仿出来的虚拟DOM 树也会包含大量的节点,想要快速对比新旧两棵虚拟DOM 树,并得出它们之间的不同,需要有一个能实现快速对比的DIFF 算法。想要实现真正高效的虚拟DOM 树需要重点对比两个问题,比较两棵DOM 树的方法和记录节点之间差异的方法。
通常来说,真正完整地比较新旧两棵虚拟DOM 树是具有相当大的计算量的,根据前端页面中的通常操作来讲,页面中数据的更新很少会是跨级别的修改DOM节点。所以,在此优化过程中只需考虑同级别的节点互相比较。
2.2.3 差异对象的应用
根据之前得到的差异对象,同时结合旧的虚拟DOM树,得到在真实DOM 树中需要修改的节点,进行真正的DOM 操作,对应修改真实的DOM 结构。
2.3 验证虚拟DOM 的性能
上文陈述了虚拟DOM 带来的好处以及理论上对应用页面的性能提升。为了验证虚拟DOM 是否真的带来了性能的提升,设计实验验证对比直接操作DOM 和使用虚拟DOM 技术渲染页面的不同性能。根据常规应用操作考虑,设置实验的步骤,对数据进行常规操作增加节点测试两种不同的方案会对页面渲染性能带来什么样不同的影响,得到直接操作DOM 和使用虚拟DOM 技术对页面节点更新的性能对比。实验的具体流程为,首先创建框架ul节点,之后使用ul 节点,在其内初始化li 节点之后,进行增加节点的操作,并增加对不同数量的节点变化响应时间的记录,结果如图2 所示。
图2 虚拟DOM 和直接操作DOM 性能消耗对比图
由图2 数据可知,随着需要操作节点数量的不断增加,使用虚拟DOM 技术实现应用中节点更新的速度更高。
3 基于虚拟DOM 的应用
一个成熟的应用首先要确保页面的流畅度和实现交互功能的响应速度,使用虚拟DOM 技术优化页面的渲染速度。根据虚拟DOM 技术以及其他的工程化的编码思路,在此基础上构建一个可视化构建商城页面应用,可用于用户快速生成H5 页面。商城页面构建应用中包含有很多对节点进行改动的操作,同时为了构建商城页面的各个显示部分和功能需求,还会存在很多的节点变动,是可以发挥出虚拟DOM 优势的理想应用。
3.1 应用结构
为了完成可视化构建商城页面的应用,最重点核心的功能是把商城页面功能模块搭建并组合起来,应用主要分为构成组件列表,效果预览画布,具体组件属性控制调整列表三大模块,如图3 所示。
图3 可视化商城构建应用页面展示图
图3 中,左侧组件列表中包含页面中常用的商城页面结构,包括标题,文字段介绍详细内容,轮播图,魔方栅格显示图片等。用户可以在组件列表中拖拽需要的功能,会在中间预览画布模块中显示相应的部分,并在右侧组件属性控制模块中调整具体的属性。
3.2 具体实现
在应用的构成组件列表中,每一个组件都可以使用JSON 数据格式详细地描述该组件的信息。应用过程中组件信息通过操作传入后,应用解析组件属性数据,生成相应的该组件的属性控制面板。例如一个商品标题,其构造是一个基础的Form 表单,其中包含属性有标题(label),类型(type),值(value),占位符(placeholder)等属性,以代码的形式展示为:
此标题为基础类型的组件,更复杂的一系列信息,也可以通过组合形式,把每一个小组件为一个对象或者数组,多个组件嵌套形成大的复合类型组件。
4 结束语
本文介绍的虚拟DOM 技术,能够在页面频繁变动需要重新渲染页面时,能够高效地定位到发生变动的节点处,完成页面的渲染。虚拟DOM 能够高效地定位需要修改的节点并完成渲染。因此,虚拟DOM 是一种提升渲染速度的有效手段。但是在页面更新并不频繁时,渲染速度只能和直接进行DOM 操作的方案旗鼓相当,甚至页面变动节点数量特小时,渲染速度相对较弱。所以在实际项目开发过程中,要根据产品页面的需求,决定是否选择使用虚拟DOM 技术。如果只是单纯的静态展示页面,不具有过多的交互功能和节点变动时,使用直接操作DOM 树的方案更加方便;若页面包含文档过多且频繁更新,选择使用虚拟DOM 技术则更加具有优势。