四:React進(jìn)階二 (虛擬DOM)

擴(kuò)展:深入Vue2.x的虛擬DOM diff原理

第一種渲染

  1. state 數(shù)據(jù)
  2. JSX 模板
  3. 數(shù)據(jù) + 模板 結(jié)合 荷憋, 生成真實(shí)的DOM辙纬,來顯示
  4. state 發(fā)生改變
  5. 數(shù)據(jù) + 模板 結(jié)合 衡楞, 生成真實(shí)的DOM,替換原始的DOM

缺陷:
第一次生成了一個完整的DOM片段
第二次生成了一個完整的DOM片段
第二次的DOM替換第一次的DOM,非常耗性能


第二種渲染

  1. state 數(shù)據(jù)
  2. JSX 模板
  3. 數(shù)據(jù) + 模板 結(jié)合 月劈, 生成真實(shí)的DOM呜袁,來顯示
  4. state 發(fā)生改變
*****************************
  5. 數(shù)據(jù) + 模板 結(jié)合 敌买, 生成真實(shí)的DOM,并不直接替換原始的DOM
  6. 新的DOM(DoucumentFragment(文檔碎片)) 和原始的DOM 做比對阶界, 找差異
  7. 找出input 框發(fā)生了變化
  8. 只用新的DOM 中的input元素虹钮,替換掉老的DOM中的input元素

注:DoucumentFragment(文檔碎片):還在內(nèi)存里,還沒有掛載到頁面

缺陷:
性能的提升并不明顯

第三種渲染

  1. state 數(shù)據(jù)
  2. JSX 模板
  3. 數(shù)據(jù) + 模板 結(jié)合 膘融, 生成真實(shí)的DOM芙粱,來顯示
<div id='abc'> <span> hello world </span> </div>
**********************
  4. 生成虛擬DOM(虛擬DOM就是一個JS對象,用它來描述真實(shí)DOM)(損耗了性能)
['div',{id:'abc},['span',{},'hello world']]
  5. state 發(fā)生變化
  6. 數(shù)據(jù)+ 模板生成新的虛擬DOM (極大的提升了性能)
['div',{id:'abc},['span',{},'bye bye']]
  7. 比較原始虛擬DOM 和新的虛擬DOM的區(qū)別氧映,找到區(qū)別是span中內(nèi)容 (極大的提升了性能)
  8. 直接操作DOM 宅倒, 改變span中的內(nèi)容

損耗比較:JS創(chuàng)建一個JS對象,遠(yuǎn)比JS創(chuàng)建一個DOM元素?fù)p耗要小屯耸,因?yàn)镴S創(chuàng)建DOM的時(shí)候需要調(diào)用web application級別的一個api

引入虛擬DOM能提高性能原理:減少了真實(shí)DOM 的創(chuàng)建和JS DOM的對比拐迁,而是去創(chuàng)建JS對象和對比JS對象

實(shí)際上:

  1. state 數(shù)據(jù)
  2. JSX 模板
  3. 數(shù)據(jù) + 模板 , 生成虛擬DOM(虛擬DOM就是一個JS對象,用它來描述真實(shí)DOM)(損耗了性能)
  ['div',{id:'abc},['span',{},'hello world']]
  4. 用虛擬DOM的結(jié)構(gòu)生成真實(shí)的DOM 疗绣, 來顯示
<div id='abc'> <span> hello world </span> </div>
  5. state 發(fā)生變化
  6. 數(shù)據(jù)+ 模板 生成新的虛擬DOM  (極大的提升了性能)
['div',{id:'abc},['span',{},'bye bye']]
  7. 比較原始虛擬DOM 和新的虛擬DOM的區(qū)別线召,找到區(qū)別是span中內(nèi)容 (極大的提升了性能)
  8. 直接操作DOM , 改變span中的內(nèi)容

優(yōu)點(diǎn):
1.性能提升了
2. 它使得跨端應(yīng)用得以實(shí)現(xiàn)多矮。React Native

render函數(shù)中:JSX → createElement → 虛擬 DOM(JS 對象)→ 真實(shí)的 DOM

虛擬DOM的diff算法

  • setState是個異步函數(shù)缓淹,是為了提高react底層性能


React中如果在短時(shí)間內(nèi)(例如一個函數(shù)體里)連續(xù)執(zhí)行了三次setState操作,React會把三次setState合并成一次setState塔逃,只進(jìn)行一次虛擬DOM的diff比對讯壶,最后只更新一次DOM。

  • 同層比對


  • React的diff算法核心:同級比較湾盗,一比較一層伏蚊,有差異整體替換。diff算從虛擬DOM樹的根節(jié)點(diǎn)進(jìn)行比較格粪,如果根節(jié)點(diǎn)就存在差異躏吊,就不會再比較下層節(jié)點(diǎn)氛改,則會把原虛擬DOM該層節(jié)點(diǎn)下的DOM全部刪除,用新的虛擬DOM重新生成一遍頁面上綁定的虛擬DOM比伏,再用頁面綁定的虛擬DOM重新生成頁面上的真實(shí)DOM胜卤。
  • diff算法,同層比對赁项,算法簡單葛躏,則比對速度很快。所以雖然會浪費(fèi)DOM渲染的性能悠菜,但是它可以大大減少了兩個虛擬DOM比對上花費(fèi)的性能消耗紫新。
  • diff過程


  • key值的作用


  • 例子:一個虛擬DOM上的數(shù)組結(jié)構(gòu)做循環(huán),渲染到了頁面上李剖。在沒有key值時(shí),數(shù)據(jù)發(fā)生變化后囤耳,diff算法沒法確定新虛擬DOM和原虛擬DOM元素間的關(guān)系篙顺,好比新的a變了,對應(yīng)老的a到底是數(shù)組中的哪個元素呢充择?diff算法只能寫雙循環(huán)遍歷確定德玫,這樣就會造成很大的性能開銷。而假如椎麦,在對虛擬DOM數(shù)組做循環(huán)時(shí)給每個最外層父節(jié)點(diǎn)設(shè)置key值取名字后宰僧,新a變化后立馬就能抓到對應(yīng)老a來對比,好的观挎,你變化琴儿,那么把a(bǔ)這個節(jié)點(diǎn)樹整顆替換即可,再例如數(shù)組push了新元素z嘁捷,diff算法一看key造成,原來沒它,就生成新DOM樹即可雄嚣。
  • 實(shí)例:循環(huán)是用index做key值晒屎。例如['a','b', 'c'],循環(huán)拿index做key值缓升,當(dāng)我們刪除a時(shí)鼓鲁,新數(shù)組對應(yīng)的就是 ['b':0, 'c': 1],好的diff算法一上來看到key值港谊,怎么“全變了”骇吭,好吧,沒辦法歧寺,只能去重新這棵節(jié)點(diǎn)數(shù)绵跷!而當(dāng)我們用穩(wěn)定的唯一值做key值時(shí)膘螟,刪除a元素后,diff算法比較后只會把dom樹上的a節(jié)點(diǎn)刪除碾局,節(jié)省了渲染的性能荆残。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市净当,隨后出現(xiàn)的幾起案子内斯,更是在濱河造成了極大的恐慌,老刑警劉巖像啼,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俘闯,死亡現(xiàn)場離奇詭異,居然都是意外死亡忽冻,警方通過查閱死者的電腦和手機(jī)真朗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來僧诚,“玉大人遮婶,你說我怎么就攤上這事『浚” “怎么了旗扑?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長慈省。 經(jīng)常有香客問我臀防,道長,這世上最難降的妖魔是什么边败? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任袱衷,我火速辦了婚禮,結(jié)果婚禮上笑窜,老公的妹妹穿的比我還像新娘祟昭。我一直安慰自己,他們只是感情好怖侦,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布篡悟。 她就那樣靜靜地躺著,像睡著了一般匾寝。 火紅的嫁衣襯著肌膚如雪搬葬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天艳悔,我揣著相機(jī)與錄音急凰,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛抡锈,可吹牛的內(nèi)容都是我干的疾忍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼床三,長吁一口氣:“原來是場噩夢啊……” “哼一罩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起撇簿,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤聂渊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后四瘫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汉嗽,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年找蜜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饼暑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡洗做,死狀恐怖弓叛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情竭望,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布裕菠,位于F島的核電站咬清,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏奴潘。R本人自食惡果不足惜旧烧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望画髓。 院中可真熱鬧掘剪,春花似錦、人聲如沸奈虾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肉微。三九已至匾鸥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碉纳,已是汗流浹背勿负。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留劳曹,地道東北人奴愉。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓琅摩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锭硼。 傳聞我的和親對象是個殘疾皇子房资,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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