久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      vuejs是虛擬DOM嗎

      vuejs是虛擬DOM的;Vue.js2.0就引入了Virtual DOM(虛擬DOM)機(jī)制,這讓初始渲染速度提升了2-4倍,并大大降低了內(nèi)存消耗。虛擬DOM的優(yōu)勢(shì):可以跨平臺(tái)、提高效率、提升渲染性能等。

      vuejs是虛擬DOM嗎

      本教程操作環(huán)境:windows7系統(tǒng)、vue2.9.6版,DELL G3電腦。

      Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并大大降低了內(nèi)存消耗。那么,什么是Virtual DOM?為什么需要Virtual DOM?它是通過(guò)什么方式去提升頁(yè)面渲染效率的呢?這是本文所要探討的問(wèn)題。

      模板轉(zhuǎn)換成視圖的過(guò)程

      在正式介紹 Virtual Dom之前,我們有必要先了解下模板轉(zhuǎn)換成視圖的過(guò)程整個(gè)過(guò)程(如下圖):

      • Vue.js通過(guò)編譯將template 模板轉(zhuǎn)換成渲染函數(shù)(render ) ,執(zhí)行渲染函數(shù)就可以得到一個(gè)虛擬節(jié)點(diǎn)樹(shù)
      • 在對(duì) Model 進(jìn)行操作的時(shí)候,會(huì)觸發(fā)對(duì)應(yīng) Dep 中的 Watcher 對(duì)象。Watcher 對(duì)象會(huì)調(diào)用對(duì)應(yīng)的 update 來(lái)修改視圖。這個(gè)過(guò)程主要是將新舊虛擬節(jié)點(diǎn)進(jìn)行差異對(duì)比,然后根據(jù)對(duì)比結(jié)果進(jìn)行DOM操作來(lái)更新視圖。

      簡(jiǎn)單點(diǎn)講,在Vue的底層實(shí)現(xiàn)上,Vue將模板編譯成虛擬DOM渲染函數(shù)。結(jié)合Vue自帶的響應(yīng)系統(tǒng),在狀態(tài)改變時(shí),Vue能夠智能地計(jì)算出重新渲染組件的最小代價(jià)并應(yīng)到DOM操作上。

      vuejs是虛擬DOM嗎

      我們先對(duì)上圖幾個(gè)概念加以解釋:

      • 渲染函數(shù):渲染函數(shù)是用來(lái)生成Virtual DOM的。Vue推薦使用模板來(lái)構(gòu)建我們的應(yīng)用界面,在底層實(shí)現(xiàn)中Vue會(huì)將模板編譯成渲染函數(shù),當(dāng)然我們也可以不寫(xiě)模板,直接寫(xiě)渲染函數(shù),以獲得更好的控制。

      • VNode 虛擬節(jié)點(diǎn):它可以代表一個(gè)真實(shí)的 dom 節(jié)點(diǎn)。通過(guò) createElement 方法能將 VNode 渲染成 dom 節(jié)點(diǎn)。簡(jiǎn)單地說(shuō),vnode可以理解成節(jié)點(diǎn)描述對(duì)象,它描述了應(yīng)該怎樣去創(chuàng)建真實(shí)的DOM節(jié)點(diǎn)。

      • patch(也叫做patching算法):虛擬DOM最核心的部分,它可以將vnode渲染成真實(shí)的DOM,這個(gè)過(guò)程是對(duì)比新舊虛擬節(jié)點(diǎn)之間有哪些不同,然后根據(jù)對(duì)比結(jié)果找出需要更新的的節(jié)點(diǎn)進(jìn)行更新。這點(diǎn)我們從單詞含義就可以看出, patch本身就有補(bǔ)丁、修補(bǔ)的意思,其實(shí)際作用是在現(xiàn)有DOM上進(jìn)行修改來(lái)實(shí)現(xiàn)更新視圖的目的。Vue的Virtual DOM Patching算法是基于Snabbdom的實(shí)現(xiàn),并在些基礎(chǔ)上作了很多的調(diào)整和改進(jìn)。

      Virtual DOM 是什么?

      Virtual DOM 其實(shí)就是一棵以 JavaScript 對(duì)象( VNode 節(jié)點(diǎn))作為基礎(chǔ)的樹(shù),用對(duì)象屬性來(lái)描述節(jié)點(diǎn),實(shí)際上它只是一層對(duì)真實(shí) DOM 的抽象。最終可以通過(guò)一系列操作使這棵樹(shù)映射到真實(shí)環(huán)境上。

      簡(jiǎn)單來(lái)說(shuō),可以把Virtual DOM 理解為一個(gè)簡(jiǎn)單的JS對(duì)象,并且最少包含標(biāo)簽名( tag)、屬性(attrs)和子元素對(duì)象( children)三個(gè)屬性。不同的框架對(duì)這三個(gè)屬性的命名會(huì)有點(diǎn)差別。

      對(duì)于虛擬DOM,咱們來(lái)看一個(gè)簡(jiǎn)單的實(shí)例,就是下圖所示的這個(gè),詳細(xì)的闡述了模板 → 渲染函數(shù) → 虛擬DOM樹(shù) → 真實(shí)DOM的一個(gè)過(guò)程

      vuejs是虛擬DOM嗎

      Virtual DOM 作用是什么?

      虛擬DOM的最終目標(biāo)是將虛擬節(jié)點(diǎn)渲染到視圖上。但是如果直接使用虛擬節(jié)點(diǎn)覆蓋舊節(jié)點(diǎn)的話(huà),會(huì)有很多不必要的DOM操作。例如,一個(gè)ul標(biāo)簽下很多個(gè)li標(biāo)簽,其中只有一個(gè)li有變化,這種情況下如果使用新的ul去替代舊的ul,因?yàn)檫@些不必要的DOM操作而造成了性能上的浪費(fèi)。

      為了避免不必要的DOM操作,虛擬DOM在虛擬節(jié)點(diǎn)映射到視圖的過(guò)程中,將虛擬節(jié)點(diǎn)與上一次渲染視圖所使用的舊虛擬節(jié)點(diǎn)(oldVnode)做對(duì)比,找出真正需要更新的節(jié)點(diǎn)來(lái)進(jìn)行DOM操作,從而避免操作其他無(wú)需改動(dòng)的DOM。

      其實(shí)虛擬DOM在Vue.js主要做了兩件事:

      • 提供與真實(shí)DOM節(jié)點(diǎn)所對(duì)應(yīng)的虛擬節(jié)點(diǎn)vnode
      • 將虛擬節(jié)點(diǎn)vnode和舊虛擬節(jié)點(diǎn)oldVnode進(jìn)行對(duì)比,然后更新視圖

      為何需要Virtual DOM?

      • 具備跨平臺(tái)的優(yōu)勢(shì)

      由于 Virtual DOM 是以 JavaScript 對(duì)象為基礎(chǔ)而不依賴(lài)真實(shí)平臺(tái)環(huán)境,所以使它具有了跨平臺(tái)的能力,比如說(shuō)瀏覽器平臺(tái)、Weex、Node 等。

      • 操作 DOM 慢,js運(yùn)行效率高。我們可以將DOM對(duì)比操作放在JS層,提高效率。

      因?yàn)镈OM操作的執(zhí)行速度遠(yuǎn)不如Javascript的運(yùn)算速度快,因此,把大量的DOM操作搬運(yùn)到Javascript中,運(yùn)用patching算法來(lái)計(jì)算出真正需要更新的節(jié)點(diǎn),最大限度地減少DOM操作,從而顯著提高性能。

      Virtual DOM 本質(zhì)上就是在 JS 和 DOM 之間做了一個(gè)緩存??梢灶?lèi)比 CPU 和硬盤(pán),既然硬盤(pán)這么慢,我們就在它們之間加個(gè)緩存:既然 DOM 這么慢,我們就在它們 JS 和 DOM 之間加個(gè)緩存。CPU(JS)只操作內(nèi)存(Virtual DOM),最后的時(shí)候再把變更寫(xiě)入硬盤(pán)(DOM)

      • 提升渲染性能

      Virtual DOM的優(yōu)勢(shì)不在于單次的操作,而是在大量、頻繁的數(shù)據(jù)更新下,能夠?qū)σ晥D進(jìn)行合理、高效的更新。

      為了實(shí)現(xiàn)高效的DOM操作,一套高效的虛擬DOM diff算法顯得很有必要。我們通過(guò)patch 的核心—-diff 算法,找出本次DOM需要更新的節(jié)點(diǎn)來(lái)更新,其他的不更新。比如修改某個(gè)model 100次,從1加到100,那么有了Virtual DOM的緩存之后,只會(huì)把最后一次修改patch到view上。那diff 算法的實(shí)現(xiàn)過(guò)程是怎樣的?

      diff 算法

      vuejs是虛擬DOM嗎

      Vue的diff算法是基于snabbdom改造過(guò)來(lái)的,僅在同級(jí)的vnode間做diff,遞歸地進(jìn)行同級(jí)vnode的diff,最終實(shí)現(xiàn)整個(gè)DOM樹(shù)的更新。因?yàn)榭鐚蛹?jí)的操作是非常少的,忽略不計(jì),這樣時(shí)間復(fù)雜度就從O(n3)變成O(n)。

      diff 算法包括幾個(gè)步驟:

      • 用 JavaScript 對(duì)象結(jié)構(gòu)表示 DOM 樹(shù)的結(jié)構(gòu);然后用這個(gè)樹(shù)構(gòu)建一個(gè)真正的 DOM 樹(shù),插到文檔當(dāng)中
      • 當(dāng)狀態(tài)變更的時(shí)候,重新構(gòu)造一棵新的對(duì)象樹(shù)。然后用新的樹(shù)和舊的樹(shù)進(jìn)行比較,記錄兩棵樹(shù)差異
      • 把所記錄的差異應(yīng)用到所構(gòu)建的真正的DOM樹(shù)上,視圖就更新了

      vuejs是虛擬DOM嗎

      diff 算法的實(shí)現(xiàn)過(guò)程

      diff 算法本身非常復(fù)雜,實(shí)現(xiàn)難度很大。本文去繁就簡(jiǎn),粗略介紹以下兩個(gè)核心函數(shù)實(shí)現(xiàn)流程:

      • patch(container,vnode) :初次渲染的時(shí)候,將VDOM渲染成真正的DOM然后插入到容器里面。
      • patch(vnode,newVnode):再次渲染的時(shí)候,將新的vnode和舊的vnode相對(duì)比,然后之間差異應(yīng)用到所構(gòu)建的真正的DOM樹(shù)上。

      1. patch(container,vnode)

      通過(guò)這個(gè)函數(shù)可以讓VNode渲染成真正的DOM,我們通過(guò)以下模擬代碼,可以了解大致過(guò)程:

      function createElement(vnode) {     var tag = vnode.tag   var attrs = vnode.attrs || {}     var children = vnode.children || []     if (!tag) {         return null     }     // 創(chuàng)建真實(shí)的 DOM 元素     var elem = document.createElement(tag)     // 屬性     var attrName     for (attrName in attrs) {         if (attrs.hasOwnProperty(attrName)) {             // 給 elem 添加屬性            elem.setAttribute(attrName, attrs[attrName])         }     }     // 子元素     children.forEach(function (childVnode) {         // 給 elem 添加子元素,如果還有子節(jié)點(diǎn),則遞歸的生成子節(jié)點(diǎn)。         elem.appendChild(createElement(childVnode))  // 遞歸     })    // 返回真實(shí)的 DOM 元素     return elem }

      2. patch(vnode,newVnode)

      這里我們只考慮vnode與newVnode如何對(duì)比的情況:

      function updateChildren(vnode, newVnode) {     var children = vnode.children || []     var newChildren = newVnode.children || []   // 遍歷現(xiàn)有的children     children.forEach(function (childVnode, index) {         var newChildVnode = newChildren[index]   // 兩者tag一樣         if (childVnode.tag === newChildVnode.tag) {             // 深層次對(duì)比,遞歸             updateChildren(childVnode, newChildVnode)         } else {    // 兩者tag不一樣            replaceNode(childVnode, newChildVnode)         }     } )}

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)