• <abbr id="chdyf"></abbr>
    <ruby id="chdyf"><acronym id="chdyf"><meter id="chdyf"></meter></acronym></ruby>
    <bdo id="chdyf"></bdo>
    <dfn id="chdyf"><menu id="chdyf"></menu></dfn>
    1. <menuitem id="chdyf"></menuitem><strong id="chdyf"><menu id="chdyf"></menu></strong>

      <rt id="chdyf"><menu id="chdyf"></menu></rt>
      成人小说一区二区三区,伊人精品成人久久综合全集观看,久久HEZYO色综合,中文字幕精品人妻熟女,影音先锋成人网站,我要看免费一级毛片,中国女人做爰A片,中文字幕av久久爽Av

      一起理解Virtual DOM

      如果您想訂閱本博客內(nèi)容,每天自動(dòng)發(fā)到您的郵箱中, 請(qǐng)點(diǎn)這里

       

      前言

      React 好像已經(jīng)火了很久很久,以致于我們對(duì)于 Virtual DOM 這個(gè)詞都已經(jīng)很熟悉了,網(wǎng)上也有非常多的介紹 React、Virtual DOM 的文章。但是直到前不久我專(zhuān)門(mén)花時(shí)間去學(xué)習(xí) Virtual DOM,才讓我對(duì) Virtual DOM 有了一定的理解,以致于要懷疑起很久之前看過(guò)的那些文章來(lái)。倒不是這些文章講得不對(duì),而是現(xiàn)在在我看來(lái)角度不太好,說(shuō)得越多,越說(shuō)不清。

      讓我能夠有所開(kāi)竅(自認(rèn)為)的,是這篇文章:


      Change And Its Detection In JavaScript Frameworks
      Monday Mar 2, 2015 by Tero Parviainen


      作者看問(wèn)題的角度很棒,從數(shù)據(jù)變更與UI同步的角度來(lái)介紹各個(gè)典型框架,特別是對(duì)于 React 的 Virtual DOM,從這個(gè)角度理解起來(lái)更容易些。

      感興趣的同學(xué),如果沒(méi)有讀過(guò)這篇文章,推薦去看一看,不感興趣就算了。不過(guò)接下來(lái)我要講的東西,部分整理自這篇文章,特別是從這篇文章中引用的圖片,非常棒。當(dāng)然還有我自己的一些思考,以及一些對(duì)于目前 Virtual DOM 實(shí)現(xiàn)的開(kāi)源庫(kù)的分析。

      如果讀了上面推薦的這篇文章,我倒是不介意你不再繼續(xù)把本文讀下去,因?yàn)橛行〇|西你已經(jīng)領(lǐng)會(huì)到了。當(dāng)然,也不反對(duì)。

      變化這件事

      談?wù)擁?yè)面的變化之前,咱們先看下數(shù)據(jù)和頁(yè)面(視覺(jué)層面的頁(yè)面)的關(guān)系。數(shù)據(jù)是隱藏在頁(yè)面底下,通過(guò)渲染展示給用戶(hù)。同樣的數(shù)據(jù),按照不同的頁(yè)面設(shè)計(jì)和實(shí)現(xiàn),會(huì)以不同形式、樣式的頁(yè)面呈現(xiàn)出來(lái)。有時(shí)候在一個(gè)頁(yè)面內(nèi)的不同位置,也會(huì)有相同數(shù)據(jù)的不同表現(xiàn)。

      1.png

      Paste_Image.png

      Web 的早期,這些頁(yè)面通常是靜態(tài)的,頁(yè)面內(nèi)容不會(huì)變化。而如果數(shù)據(jù)發(fā)生了變化,通常需要重新請(qǐng)求頁(yè)面,得到基于新的數(shù)據(jù)渲染出的新的頁(yè)面。

      2.png

      Paste_Image.png

      至少,這個(gè)模式理解起來(lái)挺簡(jiǎn)單不是嗎。

      直到 Web 應(yīng)用復(fù)雜起來(lái),開(kāi)發(fā)者們開(kāi)始關(guān)注用戶(hù)體驗(yàn),開(kāi)始將大量的處理向前端遷移,頁(yè)面變得動(dòng)態(tài)、靈活起來(lái)。一個(gè)顯著的特征是,數(shù)據(jù)發(fā)生變化之后,不再需要刷新頁(yè)面就能看到頁(yè)面上的內(nèi)容隨之更新了。

      前端需要做的事情變得多了起來(lái),前端工程師們也就修煉了起來(lái),各種前端技術(shù)也就出現(xiàn)了。

      首先,聰明的工程師們發(fā)現(xiàn)既然是在前端渲染頁(yè)面,如果只是部分?jǐn)?shù)據(jù)發(fā)生了變化,就要把頁(yè)面整體或一大塊區(qū)域重新渲染就有點(diǎn)笨了。為什么不把事情做得更些,只更新變化的數(shù)據(jù)對(duì)應(yīng)的頁(yè)面的內(nèi)容呢?

      怎么做呢?操作 DOM 唄。DOM 就是瀏覽器提供給開(kāi)發(fā)者用于操作頁(yè)面的模型嘛,直接通過(guò)腳本來(lái)調(diào)用 DOM 的各種接口就 OK 了。而且我們還有了像 jQuery 這樣的棒棒的工具,操作 DOM 變得 so easy。

      然而,頁(yè)面越來(lái)越復(fù)雜,聰明的工程師們發(fā)現(xiàn)數(shù)據(jù)變化之后,老是需要手動(dòng)編碼去操作對(duì)應(yīng)的 DOM 節(jié)點(diǎn)執(zhí)行更新,有點(diǎn)煩,不夠懶啊。于是各種框架如雨后春筍般出現(xiàn)了,紛紛表示可以簡(jiǎn)化這個(gè)過(guò)程。

      稍微早期的框架有這樣的:

      3.png

       
      Paste_Image.png

      開(kāi)發(fā)者借助框架,監(jiān)聽(tīng)數(shù)據(jù)的變更,在數(shù)據(jù)變更后更新對(duì)應(yīng)的 DOM 節(jié)點(diǎn)。雖然還是要寫(xiě)一些代碼,但是寫(xiě)出來(lái)的代碼好像很有條理的樣子,至少更容易理解和維護(hù)了,也不錯(cuò)嘛。

      更進(jìn)一步,MVVM 框架出現(xiàn)了,以 AngularJS 為代表:

      4.png

       
      Paste_Image.png

      仍然是數(shù)據(jù)變化后更新對(duì)應(yīng) DOM 節(jié)點(diǎn)的方式,但是建立這種綁定關(guān)系的過(guò)程被框架所處理,開(kāi)發(fā)者要寫(xiě)的代碼變少了,而且代碼更易讀和維護(hù)了。

      再然后呢,大家就在這個(gè)棒棒的模式上繼續(xù)深耕,紛紛表示還可以在性能上做得更好,前端領(lǐng)域一片繁榮。

      再后來(lái) React 出現(xiàn)了,它不僅不是 MVVM 框架,甚至連 MV 框架都不是。這年頭,不是個(gè) MV 框架還好意思出門(mén)?可 React 還真的帶來(lái)了新的思路!

      什么思路呢?

      就是回到過(guò)去,回到那個(gè)簡(jiǎn)單而美好的時(shí)候。具體而言,就是每次數(shù)據(jù)發(fā)生變化,就重新執(zhí)行一次整體渲染。的確這樣更簡(jiǎn)單,不用去琢磨到底是數(shù)據(jù)的哪一部分變化了,需要更新頁(yè)面的哪一部分。但是壞處太明顯,體驗(yàn)不好啊。而 React 給出了解決方案,就是 Virtual DOM。

      Virtual DOM 概況來(lái)講,就是在數(shù)據(jù)和真實(shí) DOM 之間建立了一層緩沖。對(duì)于開(kāi)發(fā)者而言,數(shù)據(jù)變化了就調(diào)用 React 的渲染方法,而 React 并不是直接得到新的 DOM 進(jìn)行替換,而是先生成 Virtual DOM,與上一次渲染得到的 Virtual DOM 進(jìn)行比對(duì),在渲染得到的 Virtual DOM 上發(fā)現(xiàn)變化,然后將變化的地方更新到真實(shí) DOM 上。

      簡(jiǎn)單來(lái)說(shuō),React 在提供給開(kāi)發(fā)者簡(jiǎn)單的開(kāi)發(fā)模式的情況下,借助 Virtual DOM 實(shí)現(xiàn)了性能上的優(yōu)化,以致于敢說(shuō)自己“不慢”。

      Virtual DOM

      React 基于 Virtual DOM 的數(shù)據(jù)更新與UI同步機(jī)制:

      5.png

       
      React – 初始渲染

      初始渲染時(shí),首先將數(shù)據(jù)渲染為 Virtual DOM,然后由 Virtual DOM 生成 DOM。

      6.png

       
      React – 數(shù)據(jù)更新

      數(shù)據(jù)更新時(shí),渲染得到新的 Virtual DOM,與上一次得到的 Virtual DOM 進(jìn)行 diff,得到所有需要在 DOM 上進(jìn)行的變更,然后在 patch 過(guò)程中應(yīng)用到 DOM 上實(shí)現(xiàn)UI的同步更新。

      Virtual DOM 作為數(shù)據(jù)結(jié)構(gòu),需要能準(zhǔn)確地轉(zhuǎn)換為真實(shí) DOM,并且方便進(jìn)行對(duì)比。除了 Virtual DOM 外,React 還實(shí)現(xiàn)了其他的特性,為了專(zhuān)注于 Virtual DOM,我另外找了兩個(gè)比較 Virtual DOM 來(lái)學(xué)習(xí):

      • virtual-dom
      • Snabbdom

      這里也推薦給感興趣且還沒(méi)有讀過(guò)兩個(gè)庫(kù)源碼的同學(xué)。

      由于只關(guān)注 Virtual DOM,通過(guò)閱讀兩個(gè)庫(kù)的源碼,對(duì)于 Virtual DOM 的定位有了更深一步的理解。

      首先看數(shù)據(jù)結(jié)構(gòu)。

      Virtual DOM 數(shù)據(jù)結(jié)構(gòu)

      DOM 通常被視為一棵樹(shù),元素則是這棵樹(shù)上的節(jié)點(diǎn)(node),而 Virtual DOM 的基礎(chǔ),就是 Virtual Node 了。

      在 virtual-dom 中,給 Virtual Node 聲明了對(duì)應(yīng)的類(lèi) VirtualNode,基本是用于存儲(chǔ)數(shù)據(jù),包括:

      • tagName
      • properties
      • children
      • key
      • namespace
      • count
      • hasWidgets
      • hasThunks
      • hooks
      • descendantHooks

      Snabbdom 的 Virtual Node 則是純數(shù)據(jù)對(duì)象,通過(guò) vnode 模塊來(lái)創(chuàng)建,對(duì)象屬性包括:

      • sel
      • data
      • children
      • text
      • elm
      • key

      雖然有所差別,除去實(shí)現(xiàn)上的差別和庫(kù)本身的額外特性,可以看到 Virtual Node 用于創(chuàng)建真實(shí)節(jié)點(diǎn)的數(shù)據(jù)包括:

      • 元素類(lèi)型
      • 元素屬性
      • 元素的子節(jié)點(diǎn)

      有了這些其實(shí)就可以創(chuàng)建對(duì)應(yīng)的真實(shí)節(jié)點(diǎn)了。

      創(chuàng)建 Virtual DOM

      嵌套 Virtual Node 就可以得到一棵樹(shù)了。virtual-dom 和 Snabbdom 都提供了函數(shù)調(diào)用的方式來(lái)創(chuàng)建 Virtual Tree,這個(gè)過(guò)程就是渲染了:

      var vTree = h('div', [
        h('span', 'hello'),
        h('span', 'world')
      ])
       

      React 提供 JSX 這顆糖,使得我們可以用類(lèi)似 HTML 的語(yǔ)法來(lái)編寫(xiě),不過(guò)編譯后實(shí)質(zhì)還是通過(guò)函數(shù)調(diào)用來(lái)得到一棵嵌套的 Virtual Tree。而且這對(duì)于理解 Virtual DOM 機(jī)制來(lái)說(shuō)不是特別重要,先不管這個(gè)。

      使用 Virtual DOM

      首先來(lái)看初始化,virtual-dom 提供了 createElement 函數(shù):

       
      var rootNode = createElement(tree)
      document.body.appendChild(rootNode)
       
      根據(jù) Virtual Node 創(chuàng)建真實(shí) DOM 元素,然后再追加到頁(yè)面上。


      再來(lái)看更新。virtual-dom 有明確的兩步操作,首先 diff,然后 patch:

      var newTree = render(count)
      var patches = diff(tree, newTree)
      rootNode = patch(rootNode, patches)


      而 Snabbdom 則簡(jiǎn)單些,只有一個(gè) patch 函數(shù),內(nèi)部在進(jìn)行比對(duì)的同時(shí)將更新應(yīng)用到了真實(shí) DOM 上,而且初始化也是用的 patch 函數(shù):

      var vnode = render(data)
      var container = document.getElementById('container')
      patch(container, vnode)
       
      // after data changed
      var newVnode = render(data)
      patch(vnode, newVnode)

       

      性能優(yōu)化

      關(guān)于性能優(yōu)化,除了 Virtual DOM 機(jī)制本身提供的特性以外,再就是不同的 Virtual DOM 庫(kù)自身的優(yōu)化方案了,這個(gè)可以看上面兩個(gè)庫(kù)的文檔,不再贅述。

      其實(shí)提到 Virtual DOM 的差異比對(duì),有人會(huì)對(duì)其內(nèi)部如何處理數(shù)組感興趣。的確,如果數(shù)組元素的位置發(fā)生了改變,這個(gè)要識(shí)別起來(lái)是有點(diǎn)麻煩。為此,上面兩個(gè)庫(kù)和 React 其實(shí)都在 Virtual Node 上額外記錄了一個(gè)屬性“key”,就是用來(lái)輔助進(jìn)行 Virtual Node 的比對(duì)的。

      簡(jiǎn)單來(lái)說(shuō),如果兩個(gè) Virtual Node 的位置不同,但是 key 屬性相同,那么會(huì)將這兩個(gè)節(jié)點(diǎn)視為由相同數(shù)據(jù)渲染得到的,然后進(jìn)一步進(jìn)行差異分析。所以,并不是僅僅按照位置進(jìn)行比對(duì),具體的實(shí)現(xiàn)可以查看各個(gè)庫(kù)的源碼。

      小結(jié)

      OK,以上就是我要講的全部所有內(nèi)容了。

      相信很多同學(xué)之前對(duì) Virtual DOM 已經(jīng)很熟悉了,比我理解得更深入的同學(xué)相信也不會(huì)少。不過(guò)從“數(shù)據(jù)變化與UI同步更新”這個(gè)角度來(lái)理解 Virtual DOM,在我看來(lái)是比較好的,所以整理在這里了。

      有個(gè)問(wèn)題挺常見(jiàn),AngularJS 和 React 哪個(gè)更好?

      如果說(shuō)各有千秋的話(huà),估計(jì)大家就“呵呵”了。但是這兩個(gè)框架/庫(kù)從“數(shù)據(jù)變化與UI同步更新”的角度來(lái)看,的確都解決了問(wèn)題,而且解決問(wèn)題的方式大家都挺認(rèn)可(至少在喜歡它們的同學(xué)眼里是這樣的)。

       

       藍(lán)藍(lán)設(shè)計(jì)m.wtxcl.cn )是一家專(zhuān)注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶(hù)體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 平面設(shè)計(jì)服務(wù)

      日歷

      鏈接

      個(gè)人資料

      存檔

      主站蜘蛛池模板: 99re在线| 强行糟蹋人妻HD中文字幕| 亚洲国产成人AV片在线播放| 成人国产亚洲精品a区天堂| aⅴ亚洲 日韩 色 图网站 播放| 亚洲午夜av| 97久久精品人人澡人人爽| 91免费视频观看| 国产美女久久久| 亚洲AV无码乱码国产精品久久| 中文字幕日产乱码中| 日韩小视频| 久久人人爽人人爽人人片AV高清| 成人自拍偷拍| 日韩av区| 尤物一区| 亚洲国产成人精品青青草原导航| 蜜桃视频成人专区在线观看| 丝袜美腿亚洲综合| Chinese国产XXXX实拍| 亚洲视频第一区第二区| 三级91| 久久国模| 宜都市| 亚洲综合精品香蕉久久网97| 四虎论坛| 亚洲美女av一区| 富川| 亚洲香蕉网久久综合影视| 国产偷伦| jizz免费| 亚洲AV无码之国产精品网址蜜芽| 洋洋AV| 粗大插入91视频| 久久人妻少妇偷人精品综合桃色 | 国产农村乱子伦精品视频| 久久精品6| 亚洲精品18| 久久亚洲粉嫩高潮的18P| 国产精品2025在线免费| 婷婷激情站|