虛擬dom,dom

前言
本文我們會(huì)先聊聊 DOM 的一些缺陷娱颊,然后在此基礎(chǔ)上介紹虛擬 DOM 是如何解決這些缺陷的傲诵,最后再站在雙緩存和 MVC 的視角來聊聊虛擬 DOM。理解了這些會(huì)讓你對(duì)目前的前端框架有一個(gè)更加底層的認(rèn)識(shí)箱硕,這也有助于你更好地理解這些前端框架拴竹。
DOM 的缺陷
比如,我們可以調(diào)用 document.body.appendChild(node)body 節(jié)點(diǎn)上添加一個(gè)元素剧罩,調(diào)用該 API 之后會(huì)引發(fā)一系列的連鎖反應(yīng)栓拜。首先渲染引擎會(huì)將 node 節(jié)點(diǎn)添加到 body 節(jié)點(diǎn)之上,然后觸發(fā)樣式計(jì)算惠昔、布局幕与、繪制、柵格化镇防、合成等任務(wù)啦鸣,我們把這一過程稱為 重排。除了重排之外来氧,還有可能引起重繪或者合成操作诫给,形象地理解就是“牽一發(fā)而動(dòng)全身”。另外啦扬,對(duì)于 DOM 的不當(dāng)操作還有可能引發(fā)強(qiáng)制同步布局和布局抖動(dòng)的問題中狂,這些操作都會(huì)大大降低渲染效率。因此扑毡,對(duì)于 DOM 的操作時(shí)我們需要非常謹(jǐn)慎胃榕。
對(duì)于一些復(fù)雜的頁面或者目前使用非常多的單頁應(yīng)用來說,其 DOM 結(jié)構(gòu)是非常復(fù)雜的瞄摊,而且還需要不斷地去修改 DOM 樹勋又,每次操作 DOM 渲染引擎都需要進(jìn)行重排、重繪或者合成等操作换帜,因?yàn)?DOM 結(jié)構(gòu)復(fù)雜赐写,所生成的頁面結(jié)構(gòu)也會(huì)很復(fù)雜,對(duì)于這些復(fù)雜的頁面膜赃,執(zhí)行一次重排或者重繪操作都是非常耗時(shí)的,這就給我們帶來了真正的性能問題揉忘。所以我們需要有一種方式來減少 JavaScript 對(duì) DOM 的操作跳座,這時(shí)候虛擬 DOM 就上場(chǎng)了端铛。
什么是虛擬 DOM?
在談?wù)撌裁词翘摂M DOM 之前疲眷,我們先來看看虛擬 DOM 到底要解決哪些事情禾蚕。

  1. 將頁面改變的內(nèi)容應(yīng)用到虛擬 DOM 上,而不是直接應(yīng)用到 DOM 上狂丝。
  2. 變化被應(yīng)用到虛擬 DOM 上時(shí)换淆,虛擬 DOM 并不急著去渲染頁面,而僅僅是調(diào)整虛擬 DOM 的內(nèi)部狀態(tài)几颜,這樣操作虛擬 DOM 的代價(jià)就變得非常輕了倍试。
  3. 在虛擬 DOM 收集到足夠的改變時(shí),再把這些變化一次性應(yīng)用到真實(shí)的 DOM 上蛋哭。

基于以上三點(diǎn)县习,我們?cè)賮砜纯词裁词翘摂M DOM。為了直觀理解谆趾,你可以參考下圖:

image.png

該圖是結(jié)合 React 流程畫的一張?zhí)摂M DOM 執(zhí)行流程圖躁愿,下面我們就結(jié)合這張圖來分析下虛擬 DOM 到底怎么運(yùn)行的。

  • 創(chuàng)建階段沪蓬。首先依據(jù) JSX 和基礎(chǔ)數(shù)據(jù)創(chuàng)建出來虛擬 DOM彤钟,它反映了真實(shí)的 DOM 樹的結(jié)構(gòu)。然后由虛擬 DOM 樹創(chuàng)建出真實(shí) DOM 樹跷叉,真實(shí)的 DOM 樹生成完后逸雹,再觸發(fā)渲染流水線往屏幕輸出頁面。
  • 更新階段性芬。如果數(shù)據(jù)發(fā)生了改變峡眶,那么就需要根據(jù)新的數(shù)據(jù)創(chuàng)建一個(gè)新的虛擬 DOM 樹;然后 React 比較兩個(gè)樹植锉,找出變化的地方辫樱,并把變化的地方一次性更新到真實(shí)的 DOM 樹上;最后渲染引擎更新渲染流水線俊庇,并生成新的頁面狮暑。

既然聊到虛擬 DOM 的更新,那我們就不得不聊聊最新的 React Fiber 更新機(jī)制了辉饱。最開始的時(shí)候搬男,比較兩個(gè)虛擬 DOM 的過程是在一個(gè)遞歸函數(shù)里執(zhí)行的伦意,其核心算法是 reconciliation案腺。通常情況下裆熙,這個(gè)比較過程執(zhí)行得很快,不過當(dāng)虛擬 DOM 比較復(fù)雜的時(shí)候慧域,執(zhí)行比較函數(shù)就有可能占據(jù)主線程比較久的時(shí)間,這樣就會(huì)導(dǎo)致其他任務(wù)的等待锯仪,造成頁面卡頓溉卓。
為了解決這個(gè)問題,React 團(tuán)隊(duì)重寫了 reconciliation 算法敦冬,新的算法稱為 Fiber reconciler辅搬,所謂的 Fiber reconciler,就是在執(zhí)行算法的過程中出讓主線程脖旱,這樣就解決了之前執(zhí)行函數(shù)占用時(shí)間過久的問題堪遂。至于具體的實(shí)現(xiàn)過程在這里就不詳細(xì)分析了,如果感興趣的話萌庆,你可以自行查閱相關(guān)資料進(jìn)行學(xué)習(xí)溶褪。
了解完虛擬 DOM 的大致執(zhí)行流程,你應(yīng)該也就知道為何需要虛擬 DOM 了踊兜。不過以上都從單純的技術(shù)視角來分析虛擬 DOM 的竿滨,那接下來我們?cè)購碾p緩存和 MVC 模型這兩個(gè)視角來聊聊虛擬 DOM。
雙緩存
使用雙緩存捏境,可以讓你先將計(jì)算的中間結(jié)果存放在另一個(gè)緩沖區(qū)中于游,等全部的計(jì)算結(jié)束,該緩沖區(qū)已經(jīng)存儲(chǔ)了完整的圖形之后垫言,再將該緩沖區(qū)的圖形數(shù)據(jù)一次性復(fù)制到顯示緩沖區(qū)贰剥,這樣就使得整個(gè)圖像的輸出非常穩(wěn)定。
在這里筷频,你可以把虛擬 DOM 看成是 DOM 的一個(gè) buffer蚌成,和圖形顯示一樣,它會(huì)在完成一次完整的操作之后凛捏,再把結(jié)果應(yīng)用到 DOM 上担忧,這樣就能減少一些不必要的更新,同時(shí)還能保證 DOM 的穩(wěn)定輸出坯癣。
MVC 模式
接下來我們?cè)賮砜纯刺摂M DOM 在 MVC 模式中所扮演的角色瓶盛。
在各大設(shè)計(jì)模式當(dāng)中,MVC 是一個(gè)非常重要且應(yīng)用廣泛的模式示罗,因?yàn)樗軐?shù)據(jù)和視圖進(jìn)行分離惩猫,在涉及到一些復(fù)雜的項(xiàng)目時(shí),能夠大大減輕項(xiàng)目的耦合度蚜点,使得程序易于維護(hù)轧房。關(guān)于 MVC 的基礎(chǔ)結(jié)構(gòu),你可以先參考下圖:

image.png

通過上圖可以發(fā)現(xiàn)绍绘,MVC 的整體結(jié)構(gòu)比較簡(jiǎn)單奶镶,由模型迟赃、視圖和控制器組成,其核心思想就是將數(shù)據(jù)和視圖分離厂镇,也就是說視圖和模型之間是不允許直接通信的捺氢,它們之間的通信是通過控制器來完成的。
比如在分析 React 項(xiàng)目時(shí)剪撬,我們可以把 React 的部分看成是一個(gè) MVC 中的視圖,在項(xiàng)目中結(jié)合 Redux 就可以構(gòu)建一個(gè) MVC 的模型結(jié)構(gòu)悠反,如下圖所示:

image.png

在該圖中残黑,我們可以把虛擬 DOM 看成是 MVC 的視圖部分,其控制器和模型都是由 Redux 提供的斋否。其具體實(shí)現(xiàn)過程如下:

  • 圖中的控制器是用來監(jiān)控 DOM 的變化梨水,一旦 DOM 發(fā)生變化,控制器便會(huì)通知模型茵臭,讓其更新數(shù)據(jù)疫诽。
  • 模型數(shù)據(jù)更新好之后,控制器會(huì)通知視圖旦委,告訴它模型的數(shù)據(jù)發(fā)生了變化奇徒。
  • 視圖接收到更新消息之后,會(huì)根據(jù)模型所提供的數(shù)據(jù)來生成新的虛擬 DOM缨硝。
  • 新的虛擬 DOM 生成好之后摩钙,就需要與之前的虛擬 DOM 進(jìn)行比較,找出變化的節(jié)點(diǎn)查辩。
  • 比較出變化的節(jié)點(diǎn)之后胖笛,React 將變化的虛擬節(jié)點(diǎn)應(yīng)用到 DOM 上,這樣就會(huì)觸發(fā) DOM 節(jié)點(diǎn)的更新宜岛。
  • DOM 節(jié)點(diǎn)的變化又會(huì)觸發(fā)后續(xù)一系列渲染流水線的變化长踊,從而實(shí)現(xiàn)頁面的更新。

在實(shí)際工程項(xiàng)目中萍倡,你需要學(xué)會(huì)分析出各個(gè)模塊身弊,并梳理出它們之間的通信關(guān)系,這樣對(duì)于任何框架你都能輕松上手了遣铝。

參考來源

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佑刷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子酿炸,更是在濱河造成了極大的恐慌瘫絮,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件填硕,死亡現(xiàn)場(chǎng)離奇詭異麦萤,居然都是意外死亡鹿鳖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門壮莹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翅帜,“玉大人,你說我怎么就攤上這事命满±缘危” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵胶台,是天一觀的道長(zhǎng)歼疮。 經(jīng)常有香客問我,道長(zhǎng)诈唬,這世上最難降的妖魔是什么韩脏? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮铸磅,結(jié)果婚禮上赡矢,老公的妹妹穿的比我還像新娘。我一直安慰自己阅仔,他們只是感情好吹散,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著霎槐,像睡著了一般送浊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丘跌,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天袭景,我揣著相機(jī)與錄音,去河邊找鬼闭树。 笑死耸棒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的报辱。 我是一名探鬼主播与殃,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼碍现!你這毒婦竟也來了幅疼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤昼接,失蹤者是張志新(化名)和其女友劉穎爽篷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慢睡,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逐工,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年铡溪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泪喊。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棕硫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出袒啼,到底是詐尸還是另有隱情哈扮,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布蚓再,位于F島的核電站灶泵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏对途。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一髓棋、第九天 我趴在偏房一處隱蔽的房頂上張望实檀。 院中可真熱鬧,春花似錦按声、人聲如沸膳犹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽须床。三九已至,卻和暖如春渐裂,著一層夾襖步出監(jiān)牢的瞬間豺旬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工柒凉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留族阅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓膝捞,卻偏偏與公主長(zhǎng)得像坦刀,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蔬咬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • 概念 虛擬DOM 是什么:其實(shí)就是個(gè)js對(duì)象虛擬 dom 是相對(duì)于瀏覽器所渲染出來的真實(shí) dom 的鲤遥,在react...
    張德瘦嬢嬢閱讀 249評(píng)論 0 0
  • visual Dom是什么?? 虛擬DOM其實(shí)就是,像擁有類似dom的一系列屬性的對(duì)象林艘,包括:標(biāo)簽名盖奈,標(biāo)簽上的屬性,...
    Adder閱讀 134評(píng)論 0 2
  • 因?yàn)镽eact北启、Vue框架的出現(xiàn)卜朗,頁面渲染采用了更高效的虛擬DOM拔第。 一個(gè)dom元素中有許多屬性,操作dom是很耗...
    一洼世界閱讀 1,472評(píng)論 0 1
  • 虛擬 DOM 的優(yōu)點(diǎn) 減少 DOM 操作 剛剛我們說過了场钉,DOM 操作是跨線程的蚊俺,性能并不好,但寫網(wǎng)頁又不得不操作...
    默_淰閱讀 133評(píng)論 0 0
  • 原文鏈接:http://reactkungfu.com/2015/10/the-difference-betwee...
    Hector526閱讀 548評(píng)論 0 0