React 虛擬DOM的理解
React框架現(xiàn)在用的人非常多律罢,React為何如此受歡迎?我想原因是引入了虛擬DOM的概念稿饰,從而使得性能有所提升吧缰儿。為什么引入虛擬DOM性能就有提升了畦粮?下面我想來說一說虛擬DOM的原理。
什么是虛擬DOM?
React中宣赔,先將真實的DOM抽象成一個JavaScript對象预麸,也就是虛擬DOM。比如儒将,我們可以構(gòu)造一個虛擬DOM:
var element = {
element: 'ul',
props: {
id:"ulist"
},
children: [
{ element: 'li', props: { id:"first" }, children: ['這是第一個List元素'] },
{ element: 'li', props: { id:"second" }, children: ['這是第二個List元素'] }
]
}
為了后面可以調(diào)函數(shù)來將虛擬DOM對象轉(zhuǎn)換成真實DOM吏祸,我們用一個構(gòu)造函數(shù)將上面的對象封裝下:
function Element( tagname, props, children )
{
this.TagName = tagname;
this.props = props;
this.children = children;
}
var u = new Element( 'ul', { id: 'ulist'}, [
new Element( 'li', { id:"first" }, ['這是第一個List元素']),
new Element( 'li', { id:"first" }, ['這是第一個List元素'])
]);
這時候的e 就是一個Element對象,里面包含TagName,props以及children屬性钩蚊,并且children也是Element對象贡翘。下來我們來思考下如何將這個對象轉(zhuǎn)換成真實的DOM結(jié)構(gòu)。
Element.prototype.render = function( ) {
var d = document.createElement( this.TagName );
for( key in this.props) {
d.setAttribute( key, this.props[key] );
}
this.children.forEach( function(child){
if(child instanceof Element) {
tnode = child.render();
}
else
{
tnode = document.createTextNode(child);
}
d.appendChild(tnode);
})
return d;
}
let ele = u.render();
document.body.appendChild(ele);
這樣就把我們構(gòu)造的虛擬DOM對象轉(zhuǎn)換成真實DOM砰逻,并呈現(xiàn)到頁面上了鸣驱。
React中虛擬DOM原理
在React中,也有一個render函數(shù)來將虛擬DOM樹蝠咆,并且踊东,React中有state轉(zhuǎn)移的過程,所以每次state有變化之后勺美,就會觸發(fā)render函數(shù)递胧,重新構(gòu)造一個虛擬DOM樹碑韵。對比新舊虛擬DOM樹的差別赡茸,記錄下差異,然后只針對差異部分對應(yīng)的真實DOM進(jìn)行操作祝闻。
如何進(jìn)行新舊虛擬DOM樹的對比呢占卧?
這里采用的是Diff算法。Diff算法比較復(fù)雜联喘,主要的思路是這樣的华蜒。
首先,每一次生成的虛擬DOM樹上的各個節(jié)點都對應(yīng)唯一的一個id豁遭,當(dāng)?shù)诙紊闪诵碌腄OM樹時叭喜,對原來樹上的每一個節(jié)點對比新樹上對應(yīng)節(jié)點,如果不同蓖谢,就記錄下來這個差異捂蕴。同時,差異也分為很多種:
替換節(jié)點闪幽;
修改屬性啥辨;
對文本內(nèi)容修改
移動、刪除盯腌、增加節(jié)點溉知;
對每一類記錄下差異之后,針對不同的差異進(jìn)行不同的操作。
算法實現(xiàn)
4.1 步驟一:用JS對象模擬DOM樹
4.2 步驟二:比較兩棵虛擬DOM樹的差異
4.3 步驟三:把差異應(yīng)用到真正的DOM樹上
比如级乍,替換節(jié)點就需要調(diào)原生JS的repaceChild()接口舌劳;對于修改屬性,則要調(diào)setAttribute()接口等等玫荣。
至于具體算法的細(xì)節(jié)蒿囤,暫時還沒有深究,希望有興趣的可以一起交流崇决。
--------------------- 本文來自 鐺鐺鐺鐺Huan 的CSDN 博客 材诽,全文地址請點擊:https://blog.csdn.net/u010046318/article/details/77340188?utm_source=copy