下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】如何使用React虚拟DOM
在下给大家分享一下如何使用React虚拟DOM,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!在Web开发中,需要将数据的变化实时反映到UI上,这时就需要对DOM进行操作,但是复杂或频繁的DOM操作通常是性能瓶颈产生的原因,为此,React引入了虚拟DOM(VirtualDOM)的机制。一、什么是虚拟DOM?在React中,render执行的结果得到的并不是真正的DOM节点,结果仅仅是轻量级的JavaScript对象,我们称之为virtualDOM。虚拟DOM是React的一大亮点,具有batching(批处理)和高效的Diff算法。这让我们可以无需担心性能问题而”毫无顾忌”的随时“刷新”整个页面,由虚拟DOM来确保只对界面上真正变化的部分进行实际的DOM操作。在实际开发中基本无需关心虚拟DOM是如何运作的,但是理解其运行机制不仅有助于更好的理解React组件的生命周期,而且对于进一步优化React程序也会有很大帮助。二、虚拟DOMVS直接操作原生DOM?如果没有VirtualDOM,简单来说就是直接重置innerHTML。这样操作,在一个大型列表所有数据都变了的情况下,还算是合理,但是,当只有一行数据发生变化时,它也需要重置整个innerHTML,这时候显然就造成了大量浪费。比较innerHTML和VirtualDOM的重绘过程如下:innerHTML:renderhtmlstring+重新创建所有DOM元素VirtualDOM:renderVirtualDOM+diff+必要的DOM更新和DOM操作比起来,js计算是非常便宜的。VirtualDOMrender+diff显然比渲染html字符串要慢,但是,它依然是纯js层面的计算,比起后面的DOM操作来说,依然便宜了太多。当然,曾有人做过验证说React的性能不如直接操作真实DOM,代码如下:function
Raw()
{
var
data
=
_buildData(),
html
=
"";
...
for(var
i=0;
i<data.length;
i++)
{
var
render
=
template;
render
=
render.replace("{{className}}",
"");
render
=
render.replace("{{label}}",
data[i].label);
html
+=
render;
}
...
container.innerHTML
=
html;
...
}该测试用例中虽然构造了一个包含1000个Tag的String,并把它添加到DOM树中,但是只做了一次DOM操作。然而,在实际开发过程中,这1000个元素更新可能分布在20个逻辑块中,每个逻辑块中包含50个元素,当页面需要更新时,都会引起DOM树的更新,上述代码就近似变成了如下格式:function
Raw()
{
var
data
=
_buildData(),
html
=
"";
...
for(var
i=0;
i<data.length;
i++)
{
var
render
=
template;
render
=
render.replace("{{className}}",
"");
render
=
render.replace("{{label}}",
data[i].label);
html
+=
render;
if(!(i
%
50))
{
container.innerHTML
=
html;
}
}
...
}这样来看,React的性能就远胜于原生DOM操作了。而且,DOM完全不属于Javascript(也不在Javascript引擎中存在).。Javascript其实是一个非常独立的引擎,DOM其实是浏览器引出的一组让Javascript操作HTML文档的API而已。在即时编译的时代,调用DOM的开销是很大的。而VirtualDOM的执行完全都在Javascript引擎中,完全不会有这个开销。React.js相对于直接操作原生DOM有很大的性能优势,很大程度上都要归功于virtualDOM的batching和diff。batching把所有的DOM操作搜集起来,一次性提交给真实的DOM。diff算法时间复杂度也从标准的的Diff算法的O(n^3)降到了O(n)。这里留到下一次博客单独讲。三、虚拟DOMVSMVVM?相比起React,其他MVVM系框架比如Angular,Knockout以及Vue、Avalon采用的都是数据绑定:通过Directive/Binding对象,观察数据变化并保留对实际DOM元素的引用,当有数据变化时进行对应的操作。MVVM的变化检查是数据层面的,而React的检查是DOM结构层面的。MVVM的性能也根据变动检测的实现原理有所不同:Angular的脏检查使得任何变动都有固定的O(watchercount)的代价;Knockout/Vue/Avalon都采用了依赖收集,在js和DOM层面都是O(change):脏检查:scopedigest+必要DOM更新依赖收集:重新收集依赖+必要DOM更新可以看到,Angular最不效率的地方在于任何小变动都有的和watcher数量相关的性能代价。但是!当所有数据都变了的时候,Angular其实并不吃亏。依赖收集在初始化和数据变化的时候都需要重新收集依赖,这个代价在小量更新的时候几乎可以忽略,但在数据量庞大的时候也会产生一定的消耗。MVVM渲染列表的时候,由于每一行都有自己的数据作用域,所以通常都是每一行有一个对应的ViewModel实例,或者是一个稍微轻量一些的利用原型继承的"scope"对象,但也有一定的代价。所以,MVVM列表渲染的初始化几乎一定比React慢,因为创建ViewModel/scope实例比起VirtualDOM来说要昂贵很多。这里所有MVVM实现的一个共同问题就是在列表渲染的数据源变动时,尤其是当数据是全新的对象时,如何有效地复用已经创建的ViewModel实例和DOM元素。假如没有任何复用方面的优化,由于数据是“全新”的,MVVM实际上需要销毁之前的所有实例,重新创建所有实例,最后再进行一次渲染!这就是为什么题目里链接的angular/knockout实现都相对比较慢。相比之下,React的变动检查由于是DOM结构层面的,即使是全新的数据,只要最后渲染结果没变,那么就不需要做无用功。Angular和Vue都提供了列表重绘的优化机制,也就是“提示”框架如何有效地复用实例和DOM元素。比如数据库里的同一个对象,在两次前端API调用里面会成为不同的对象,但是它们依然有一样的uid。这时候你就可以提示trackbyuid来让Angular知道,这两个对象其实是同一份数据。那么原来这份数据对应的实例和DOM元素都可以复用,只需要更新变动了的部分。或者,你也可以直接trackby$index来进行“原地复用”:直接根据在数组里的位置进行复用。在题目给出的例子里,如果angular实现加上trackby$index的话,后续重绘是不会比React慢多少的。甚至在dbmonster测试中,Angular和Vue用了trackby$index以后都比React快:dbmon(注意Angular默认版本无优化,优化过的在下面)在比较性能的时候,要分清楚初始渲染、小量数据更新、大量数据更新这些不同的场合。VirtualDOM、脏检查MVVM、数据收集MVVM在不同场合各有不同的表现和不同的优化需求。VirtualDOM为了提升小量数据更新时的性能,也需要针对性的优化,比如shouldComponentUpdate或是immutabledata。初始渲染:VirtualDOM>脏检查>=依赖收集小量数据更新:依赖收集>>VirtualDOM+优化>脏检查(无法优化)>VirtualDOM无优化大量数据更新:脏检查+优化>=依赖收集+优化>VirtualDOM(无法/无需优化)>>MVVM无优化(该段落借鉴了知乎的相关回答)四、对React虚拟DOM的误解?React从来没有说过“React比原生操作DOM快”。React给我们的保证是,在不需要手动优化的情况下,它依然可以给我们提供过得去的性能。React掩盖了底层的DOM操作,可以用更声明式
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年金融服务采购合同创新金融产品合作协议2篇
- 导演与发行方2025年度合同3篇
- 二零二五年度餐饮泔水处理与环保设施运营管理合同6篇
- 二零二五年度高校毕业生就业见习实践基地建设合作合同3篇
- 二零二五年度航空航天设备维修承包合同样本3篇
- 二零二五年高性能混凝土委托加工合同范本3篇
- 碎石买卖合同(二零二五年度)2篇
- 二零二五年度药品质量第三方检测合同范本6篇
- 二零二五版国际贸易中货物所有权转移与国际贸易政策研究合同3篇
- 2025年度电力设施租赁合同标的转让协议3篇
- 课题申报书:大中小学铸牢中华民族共同体意识教育一体化研究
- 岩土工程勘察课件0岩土工程勘察
- 《肾上腺肿瘤》课件
- 2024-2030年中国典当行业发展前景预测及融资策略分析报告
- 《乘用车越野性能主观评价方法》
- 幼师个人成长发展规划
- 2024-2025学年北师大版高二上学期期末英语试题及解答参考
- 批发面包采购合同范本
- 乘风化麟 蛇我其谁 2025XX集团年终总结暨颁奖盛典
- 2024年大数据分析公司与中国政府合作协议
- 一年级数学(上)计算题专项练习汇编
评论
0/150
提交评论