React基礎(chǔ)3--diff算法

u=911206721,762108725&fm=26&gp=0.jpg

本來想深入說一下virtual dom 與diff,但是最近很忙,就簡單聊聊react的diff算法吧。

diff算法

傳統(tǒng)的diff算法是通過循環(huán)遞歸對節(jié)點進行一次對比稀余,從而計算一棵樹型結(jié)構(gòu)轉(zhuǎn)換成另一顆屬性結(jié)構(gòu)。這種方法效率低下趋翻,如果采用這種方式進行渲染性能的消耗會異常大这溅。那么react是怎么解決這個的呢住闯?

1.dom節(jié)點跨層級的移動操作特別少咐柜,少到可以忽略不計黔龟。

react對樹的算法進行了簡明的優(yōu)化,是的dom樹通過分層比較dom的差異讨惩,并且只會對比同一層辟癌,忽略跨層級的差異
例如,對比一個父節(jié)點下所有子節(jié)點荐捻,當發(fā)現(xiàn)有一個子節(jié)點不在時黍少,即刪除該子節(jié)點下所有內(nèi)容,這樣減少了很多不必要的遍歷处面。
假如用戶出現(xiàn)了跨層級移動操作
假如厂置,在dom下有兩個節(jié)點dom1、dom2魂角。此時我們需要將dom1移植到dom2下昵济。
react發(fā)現(xiàn)dom1不見,它會不管三七二十一野揪,將整個dom1刪除砸紊,根本不會考慮dom1下子節(jié)點的問題。
但是囱挑,現(xiàn)在我們是將dom1移到dom2下了。react會執(zhí)行以下操作沼溜。
在原有dom2節(jié)點平挑,新建dom1,然后在依次新建dom1的子節(jié)點系草。
最后刪除原來dom1節(jié)點通熄。
沒錯,就是新建然后刪除操作找都。這就是react針對特殊情況的特殊對待唇辨。
但是針對這種特殊情況,會大大影響性能能耻,所以應該避免dom節(jié)點跨層操作的為標題

2.不同類的組件很少存在相似DOM的情況赏枚,只會比較同類組件

針對組件亡驰,擁有同一類的兩個組件將按照原策略進行比較,擁有不同類的兩個組件將會生成不同的樹結(jié)構(gòu)饿幅,當react判斷組件為dirty component凡辱,從而替換整個組件下所有子節(jié)點。
用戶可以通過shouldComponentUpdate()來判斷是否需要更新組件栗恩。
如果透乾,在開發(fā)中我們需要將A組件換成B組件,A與B不是同類組件時磕秤,react會毫不猶豫的刪除A乳乌,新建B及其子節(jié)點。不管A與B是否有相同的結(jié)構(gòu)市咆。
但是假如在不同類汉操,但是結(jié)構(gòu)相似的dom,將會大大影響react性能床绪。
react官方也說過客情,在開發(fā)過程中不同類型很少存在相似dom樹。

3.當節(jié)點處于同一層級時候癞己。

(1).新組建類型不存在舊的集合里膀斋,對新節(jié)點執(zhí)行插入makeInsertMarkup()
(2).舊的集合里有新的組件類型,引動操作痹雅。makeMove()
(3).舊的組件類型在新的集合里就有仰担,但是不能直接服用,或者則執(zhí)行makeRemove()操作绩社。
react通過對同一級別的同組節(jié)點添加唯一的key值摔蓝,進行區(qū)分。
react首先會對新集合循環(huán)遍歷愉耙,通過位移的key值判斷新舊集合中是否存在相同的節(jié)點贮尉,如果存在,則進行移動操作朴沿,否則不執(zhí)行操作猜谚。
執(zhí)行移動操作:
當前節(jié)點在舊集合位置mountIndex與舊集合中l(wèi)astIndex(表示訪問過的節(jié)點在舊集合中最右側(cè)的位置,會一直變化)進行比較赌渣。
如果新節(jié)點中訪問的節(jié)點比lastIndex大魏铅,證明訪問的節(jié)點比舊集合最后一個節(jié)點還靠右,因此該節(jié)點不會影響其他節(jié)點坚芜,不需要添加到差異隊列中览芳。只用小于lastIndex時,才會進行操作鸿竖。

通過上文我們可以了解react的diff將傳統(tǒng)的循環(huán)迭代比較沧竟,通過自己特有的規(guī)則铸敏,優(yōu)化了很多。規(guī)則1就是屯仗,react忽略dom節(jié)點跨層級的移動操作搞坝。其次,react只會比較同類組件魁袜。要是萬一出現(xiàn)特殊情況呢桩撮,react針對特殊情況將實現(xiàn)新增刪除操作。但是峰弹,這樣會對react本身性能有很大影響店量。
所以在開發(fā)中我們也要避免,盡量不做跨層操作鞠呈,在設(shè)計組件開發(fā)的時候融师,相似dom樹,可以想辦法設(shè)計相同的類蚁吝。當然旱爆,更要避免新增刪除dom,而是用屬性控制窘茁。最簡單的例子:
將下面代碼

if(...){
    dom = (<div>
          ....
    </div>)
}else{
    dom =null;
}

用如下代替

if(...){
      attrs = {display:'block'}
}else{
      attrs =  {display:'none'}
}
<div style={attr}>...</div>

這個例子很簡單怀伦,因為作者見到過這樣用的,(曾經(jīng)面試過這樣一個人山林,自稱熟悉房待,做過很多項目,但是...不過確實第一種很節(jié)省時間)就在這里做個反面教材驼抹。
其實在做更大的項目桑孩,開發(fā)更復雜的組件的時候,我們會針對react這些特性設(shè)計出性能更加強大的組件框冀,這才是由小白與大神真正的區(qū)別 流椒, 額--之一。這就是有可能你做了很多項目但是你依然是個小白明也,而有些人做的項目并不是很多卻已經(jīng)成為大神了镣隶。
React基礎(chǔ)1--生命周期詳解
React基礎(chǔ)2--深入挖掘setState

如果有些錯的地方歡迎留言。不過作者肯定懶得改诡右。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市轻猖,隨后出現(xiàn)的幾起案子帆吻,更是在濱河造成了極大的恐慌,老刑警劉巖咙边,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猜煮,死亡現(xiàn)場離奇詭異次员,居然都是意外死亡,警方通過查閱死者的電腦和手機王带,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門淑蔚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人愕撰,你說我怎么就攤上這事刹衫。” “怎么了搞挣?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵带迟,是天一觀的道長。 經(jīng)常有香客問我囱桨,道長仓犬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任舍肠,我火速辦了婚禮搀继,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翠语。我一直安慰自己叽躯,他們只是感情好,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布啡专。 她就那樣靜靜地躺著险毁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪们童。 梳的紋絲不亂的頭發(fā)上畔况,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音慧库,去河邊找鬼跷跪。 笑死,一個胖子當著我的面吹牛齐板,可吹牛的內(nèi)容都是我干的吵瞻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼甘磨,長吁一口氣:“原來是場噩夢啊……” “哼橡羞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起济舆,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤卿泽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后滋觉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體签夭,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡齐邦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了第租。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片措拇。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖慎宾,靈堂內(nèi)的尸體忽然破棺而出丐吓,到底是詐尸還是另有隱情,我是刑警寧澤璧诵,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布汰蜘,位于F島的核電站,受9級特大地震影響之宿,放射性物質(zhì)發(fā)生泄漏族操。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一比被、第九天 我趴在偏房一處隱蔽的房頂上張望色难。 院中可真熱鬧,春花似錦等缀、人聲如沸枷莉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笤妙。三九已至,卻和暖如春噪裕,著一層夾襖步出監(jiān)牢的瞬間蹲盘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工膳音, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留召衔,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓祭陷,卻偏偏與公主長得像苍凛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子兵志,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

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