宝哥软件园

从反应渲染过程分析差分算法

编辑:宝哥软件园 来源:互联网 时间:2021-08-30

React最惊人的部分是虚拟DOM及其高效的Diff算法。这让我们可以随时“刷新”整个页面,而不用担心性能问题,虚拟DOM保证了只有界面真正改变的部分才是实际操作的DOM。React在这部分已经足够透明了,我们基本上不需要关心虚拟DOM在实际开发中是如何工作的。然而,了解其运行机制不仅有助于更好地理解React组件的生命周期,也有助于进一步优化React程序。

1.什么是虚拟DOM

在React中,渲染执行的结果不是一个真实的DOM节点,而只是一个轻量级的JavaScript对象,我们称之为虚拟DOM。简单来说,其实所谓的虚拟DOM就是JavaScript对象到Html DOM节点的映射;也就是说,Html结构由JavaScript对象表示,这个对象就是虚拟DOM。

eg:

Html:

ul id=' list ' Li class=' item ' item 1/Li Li class=' item ' item 2/Li/ul JavaScript对象表示(虚拟DOM)

{ tagName: 'ul ',props: { id: ' list ' },children: [ {tagName: 'li ',props: { class: ' item ' },children: ['Item 1']},{tagName: 'li ',prop : { class 3360 ' Item ' },children :[' Item 2 ' },} 2。什么时候生成到虚拟DOM?

反应生命周期有三个阶段:加载、更新和卸载。附上反应生命周期图

如上所述,渲染执行的结果不是一个真实的DOM节点,而只是一个轻量级的JavaScript对象,即调用渲染函数时会创建一个虚拟的DOM;

类选项卡扩展了反应。组件{ render(){ React . createelement(' p ',{ className: 'class'},' Hello React ')} }

虚拟DOM是通过React.createElemen创建的,这个函数只在Render函数中调用,所以在React的加载和更新过程中会生成虚拟DOM;至于挂载到真实的DOM,自然是ReactDom.render函数。

3.如何实现虚拟DOM

实际上,实现非常简单,主要是定义一个函数,将我们传入的参数组成一个React元素对象,type就是我们传入的组件类型,可以是类、函数或者字符串(比如‘div’)

React的大致源代码:

函数createElement(类型、配置、子级){ let propNameconst props={ };让key=null让ref=null让self=null让source=nullif(配置!=null){ if(hasvalidref(config)){//如果有ref,则取出ref=config.ref} if (hasValidKey(config)) {//如果有密钥,取出来key=' ' config.key} self=配置。__self===未定义?null :配置。_ _自我;来源=配置。__source===未定义?null :配置。_ _来源;for(config中的propName){ if(hasowntproperty . call(config,propName)!保留_道具。hasown property(prop name)){//把ref和key以外的这些特殊属性放到新道具对象props[prop name]=config[prop name]中;} } }//获取子元素const children length=arguments . length-2;if(children length===1){ props . children=children;} else if(childlength 1){ const childArray=Array(childlength);for(设I=0;一、儿童长度;i ) { childArray[i]=参数[I ^ 2];} props.children=childArray}//添加默认道具if(type . defaultprops){ const defaultprops=type . defaultprops;for(PropName in DefaultProps){ if(props[PropName]==undefined){ props[PropName]=DefaultProps[PropName];} } }返回ReactElement(类型、键、引用、自身、源、ReactCurrentOwner.current、props、);} const React element=function(type,key,ref,self,source,owner,Props) {//得到的React element const element={//这个标记允许我们唯一地将其标识为一个React element $ $ type of : React _ element _ type,//属于元素type:类型的内置属性,key: key,ref: ref,props: props,//记录负责创建这个元素的组件。_owner: owner,};返回元素;};打印组件:

4.为什么需要使用虚拟DOM

DOM管理的历史阶段:

JS或jQuery操作DOM:随着应用越来越复杂,JS中需要维护的字段越来越多,事件回调中需要监控事件、更新页面的DOM操作也越来越多,应用变得非常难维护。后来产生了MVC和MVC架构模式,期望从代码组织模式上降低维护难度。但是,MVC架构并不能减少维护状态,在状态更新时也没有减少页面更新操作。你需要操作的DOM还是需要操作的,只是换个地方而已。既然状态改变是为了操纵对应的DOM元素,为什么不做点什么把视图绑定到状态,当状态改变时视图自动改变呢?这就是后来人们提出的MVVM模式。只要模板声明视图组件绑定到什么状态,双向绑定引擎就会在状态更新时自动更新视图;但是,MVVM双向数据绑定不是唯一的方法。还有一种非常直观的方式:一旦状态发生变化,模板引擎会重新渲染整个视图,然后用新视图替换旧视图。React采用第四种模式;但是我们都知道操作DOM的成本太高了,而且JavaScript比JavaScript快很多,可以简单的用JavaScript对象来表示Html DOM(Virtual DOM诞生了)

这种方式会导致很多问题,最大的问题是会很慢,因为即使是很小的状态改变也要重构整个DOM,性价比太低;React Virtual DOM在状态更新的过程中加入了一些特殊的操作,避免了整个DOM树的变化(它是下一个Diff算法)。

下一个Diff算法即将更新,敬请期待~ ~ ~

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

更多资讯
游戏推荐
更多+