虛擬DOM(Virtual DOM)的工作原理

1. 為什么需要虛擬DOM

先介紹瀏覽器加載一個網(wǎng)頁需要經(jīng)歷那些過程放坏;我們只討論頁面解析流程军洼,不考慮網(wǎng)絡(luò)請求過程。

瀏覽器內(nèi)核拿到html文件后璧针,大致分為一下5個步驟:

1. 解析html元素,構(gòu)建dom 樹

2. 解析CSS渊啰,生成頁面css規(guī)則樹(Style Rules)

3. 將dom樹 和 css規(guī)則樹關(guān)聯(lián)起來探橱,生成render樹

4. 布局(layout/ reflow)申屹,瀏覽器會為Render樹上的每個節(jié)點確定在屏幕上的尺寸、位置

5. 繪制Render樹隧膏,繪制頁面像素信息到屏幕上哗讥,這個過程叫paint

? ? 當(dāng)你用原生js 或jquery等庫去操作DOM時,瀏覽器會從構(gòu)建DOM樹開始講整個流程執(zhí)行一遍胞枕,所以頻繁操作DOM會引起不需要的計算杆煞,導(dǎo)致頁面卡頓,影響用戶體驗曲稼。而Virtual DOM能很好的解決這個問題索绪。它用javascript對象表示virtual node(VNode),根據(jù)VNode 計算出真實DOM需要做的最小變動贫悄,然后再操作真實DOM節(jié)點瑞驱,提高渲染效率。

2. Virtual DOM

虛擬DOM用javascript對象來表示VNode窄坦,VNode的結(jié)構(gòu)如下:

虛擬節(jié)點(vNode)結(jié)構(gòu)

下面是虛擬DOM的算法流程圖:

虛擬DOM算法流程圖

React Diff算法

高效的diff算法能夠保證進(jìn)行對實際的DOM進(jìn)行最小的變動唤反。但是標(biāo)準(zhǔn)的的 Diff 算法復(fù)雜度需要 O(n^3),這顯然無法滿足性能要求鸭津。要達(dá)到每次界面都可以整體刷新界面的目的彤侍,勢必需要對算法進(jìn)行優(yōu)化。React里結(jié)合 Web 界面的特點做出了兩個簡單的假設(shè)逆趋,使得 Diff 算法復(fù)雜度直接降低到 O(n)盏阶。

1. 兩個相同組件產(chǎn)生類似的 DOM 結(jié)構(gòu),不同的組件產(chǎn)生不同的 DOM 結(jié)構(gòu)闻书;

2. 對于同一層次的一組子節(jié)點名斟,它們可以通過唯一的 id 進(jìn)行區(qū)分。

算法上的優(yōu)化是 React 整個界面 Render 的基礎(chǔ)魄眉,保證了整體界面渲染的性能砰盐。

不同節(jié)點類型的比較

為了在樹之間進(jìn)行比較,我們首先要能夠比較兩個節(jié)點坑律,在 React 中即比較兩個虛擬 DOM 節(jié)點岩梳,當(dāng)兩個節(jié)點不同時,應(yīng)該如何處理晃择。這分為兩種情況:(1)節(jié)點類型不同 冀值,(2)節(jié)點類型相同,但是屬性不同宫屠。

節(jié)點類型不同:直接刪除原節(jié)點池摧, 插入新節(jié)點。

React 的 DOM Diff 算法實際上只會對樹進(jìn)行逐層比較激况,兩棵樹只會對同一層次的節(jié)點進(jìn)行比較如下所述。

dom樹

React 只會對相同顏色方框內(nèi)的 DOM 節(jié)點進(jìn)行比較,即同一個父節(jié)點下的所有子節(jié)點乌逐。當(dāng)發(fā)現(xiàn)節(jié)點已經(jīng)不存在竭讳,則該節(jié)點及其子節(jié)點會被完全刪除掉,不會用于進(jìn)一步的比較浙踢。這樣只需要對樹進(jìn)行一次遍歷绢慢,便能完成整個 DOM 樹的比較。

相同類型節(jié)點的比較

React 會對屬性進(jìn)行重設(shè)從而實現(xiàn)節(jié)點的轉(zhuǎn)換洛波。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胰舆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蹬挤,更是在濱河造成了極大的恐慌缚窿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焰扳,死亡現(xiàn)場離奇詭異倦零,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吨悍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門扫茅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人育瓜,你說我怎么就攤上這事葫隙。” “怎么了躏仇?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵恋脚,是天一觀的道長。 經(jīng)常有香客問我钙态,道長慧起,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任册倒,我火速辦了婚禮蚓挤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驻子。我一直安慰自己灿意,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布崇呵。 她就那樣靜靜地躺著缤剧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪域慷。 梳的紋絲不亂的頭發(fā)上荒辕,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天汗销,我揣著相機(jī)與錄音,去河邊找鬼抵窒。 笑死弛针,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的李皇。 我是一名探鬼主播削茁,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼掉房!你這毒婦竟也來了茧跋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤卓囚,失蹤者是張志新(化名)和其女友劉穎瘾杭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捍岳,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡富寿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锣夹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片页徐。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖银萍,靈堂內(nèi)的尸體忽然破棺而出变勇,到底是詐尸還是另有隱情,我是刑警寧澤贴唇,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布搀绣,位于F島的核電站,受9級特大地震影響戳气,放射性物質(zhì)發(fā)生泄漏链患。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一瓶您、第九天 我趴在偏房一處隱蔽的房頂上張望麻捻。 院中可真熱鬧,春花似錦呀袱、人聲如沸贸毕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至牵啦,卻和暖如春寇僧,著一層夾襖步出監(jiān)牢的瞬間摊腋,已是汗流浹背沸版。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留兴蒸,地道東北人推穷。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像类咧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蟹腾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355

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