react之虛擬dom和diff算法

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恒傻,隨后出現(xiàn)的幾起案子脸侥,更是在濱河造成了極大的恐慌盈厘,老刑警劉巖沸手,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件契吉,死亡現(xiàn)場離奇詭異,居然都是意外死亡菲语,警方通過查閱死者的電腦和手機(jī)惑灵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門英支,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人妄帘,你說我怎么就攤上這事把敢。” “怎么了婶恼?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蚣录。 經(jīng)常有香客問我眷篇,道長,這世上最難降的妖魔是什么蕉饼? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任昧港,我火速辦了婚禮,結(jié)果婚禮上创肥,老公的妹妹穿的比我還像新娘。我一直安慰自己叹侄,他們只是感情好趾代,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布稽坤。 她就那樣靜靜地躺著糯俗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪杖玲。 梳的紋絲不亂的頭發(fā)上淘正,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天鸿吆,我揣著相機(jī)與錄音惩淳,去河邊找鬼乓搬。 笑死代虾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棉磨。 我是一名探鬼主播江掩,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼乘瓤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起衙傀,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎差油,沒想到半個月后拗军,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡蓄喇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了妆偏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刃鳄。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钱骂,靈堂內(nèi)的尸體忽然破棺而出叔锐,到底是詐尸還是另有隱情见秽,我是刑警寧澤愉烙,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布步责,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蔗包。R本人自食惡果不足惜慧邮,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一邻储、第九天 我趴在偏房一處隱蔽的房頂上張望吨娜。 院中可真熱鬧,春花似錦淘钟、人聲如沸宦赠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勾扭。三九已至,卻和暖如春铁瞒,著一層夾襖步出監(jiān)牢的瞬間妙色,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工慧耍, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留身辨,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓芍碧,卻偏偏與公主長得像煌珊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泌豆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 參考文章:深度剖析:如何實現(xiàn)一個Virtual DOM 算法 作者:戴嘉華React中一個沒人能解釋清楚的問題——...
    waka閱讀 5,965評論 0 21
  • 我們考慮一下react優(yōu)化應(yīng)該在生命周期定庵,裝載階段基本沒有什么選擇,當(dāng)react組件第一次出現(xiàn)在dom樹中的時候踪危,...
    DCbryant閱讀 1,164評論 0 1
  • 原文:https://segmentfault.com/a/1190000010686582 React框架使用的...
    宋00閱讀 776評論 0 0
  • 七年的大學(xué)學(xué)習(xí)蔬浙,豐富了我的知識,拓展了我的視野贞远;多年的大學(xué)活動畴博,鍛煉了我的能力,增長了我的閱歷兴革。一直以為绎晃,教師的工...
    弄墨忘疲閱讀 202評論 0 2
  • 農(nóng)歷六月十八(2018.7.30)周一 早起小鬧鐘叫醒了沉睡中的彧寶,閉著眼睛關(guān)上鬧鐘杂曲,坐了起來,只見下地了袁余。等我...
    亦然愛彧閱讀 161評論 0 0