為什么需要虛擬DOM?
如果對前端工作進(jìn)行抽象的話,主要就是維護(hù)狀態(tài)和更新視圖,而更新視圖和維護(hù)狀態(tài)都需要DOM操作。其實(shí)近年來,前端的框架主要發(fā)展方向就是解放DOM操作的復(fù)雜性。
運(yùn)行js的速度是很快的,大量的操作DOM就會很慢,時(shí)常在更新數(shù)據(jù)后會重新渲染頁面,這樣造成在沒有改變數(shù)據(jù)的地方也重新渲染了DOM 節(jié)點(diǎn),這樣就造成了很大程度上的資源浪費(fèi)。
在jQuery出現(xiàn)以前,我們直接操作DOM結(jié)構(gòu),這種方法復(fù)雜度高,兼容性也較差。有了jQuery強(qiáng)大的選擇器以及高度封裝的API,我們可以更方便的操作DOM,jQuery幫我們處理兼容性問題,同時(shí)也使DOM操作變得簡單。
但是聰明的程序員不可能滿足于此,各種MVVM框架應(yīng)運(yùn)而生,有angularJS、avalon、vue.js等,MVVM使用數(shù)據(jù)雙向綁定,使得我們完全不需要操作DOM了,更新了狀態(tài),視圖會自動更新。更新了視圖數(shù)據(jù)狀態(tài)也會自動更新,可以說MVVM使得前端的開發(fā)效率大幅提升。但是其大量的事件綁定使得其在復(fù)雜場景下的執(zhí)行性能堪憂,有沒有一種兼顧開發(fā)效率和執(zhí)行效率的方案呢?由此引入Virtual DOM(虛擬DOM)。
利用在內(nèi)存中生成與真實(shí)DOM與之對應(yīng)的數(shù)據(jù)結(jié)構(gòu),這個(gè)在內(nèi)存中生成的結(jié)構(gòu)稱之為虛擬DOM 。
當(dāng)數(shù)據(jù)發(fā)生變化時(shí),能夠智能地計(jì)算出重新渲染組件的最小代價(jià)并應(yīng)用到DOM操作上。
Virtual DOM 算法
所謂的 Virtual DOM 算法。包括幾個(gè)步驟:
1.用 JavaScript 對象結(jié)構(gòu)表示 DOM 樹的結(jié)構(gòu);然后用這個(gè)樹構(gòu)建一個(gè)真正的 DOM 樹,插到文檔當(dāng)中;
2.當(dāng)狀態(tài)變更的時(shí)候,重新構(gòu)造一棵新的對象樹。然后用新的樹和舊的樹進(jìn)行比較,記錄兩棵樹差異;
3.把2所記錄的差異應(yīng)用到步驟1所構(gòu)建的真正的DOM樹上,視圖就更新了。
Virtual DOM 本質(zhì)上就是在 JS 和 DOM 之間做了一個(gè)緩存??梢灶惐?CPU 和硬盤,既然硬盤這么慢,我們就在它們之間加個(gè)緩存。
既然 DOM 這么慢,我們就在它們 JS 和 DOM 之間加個(gè)緩存。CPU(JS)只操作內(nèi)存(Virtual DOM),最后的時(shí)候再把變更寫入硬盤(DOM)。
所謂的virtual dom,也就是虛擬節(jié)點(diǎn)。它通過js的Object對象模擬DOM中的節(jié)點(diǎn),然后再通過特定的render方法將其渲染成真實(shí)的DOM節(jié)點(diǎn) dom。diff 則是通過JS層面的計(jì)算,返回一個(gè)patch對象,即補(bǔ)丁對象,在通過特定的操作解析patch對象,完成頁面的重新渲染。
比較兩棵虛擬DOM樹的差異
比較兩棵DOM樹的差異是 Virtual DOM 算法最核心的部分,這也是所謂的 Virtual DOM 的 diff 算法。
兩個(gè)樹的完全的 diff 算法是一個(gè)時(shí)間復(fù)雜度為 O(n^3) 的問題。但是在前端當(dāng)中,你很少會跨越層級地移動DOM元素。所以 Virtual DOM 只會對同一個(gè)層級的元素進(jìn)行對比:
上面的div只會和同一層級的div對比,第二層級的只會跟第二層級對比。這樣算法復(fù)雜度就可以達(dá)到 O(n)。
在實(shí)際的代碼中,會對新舊兩棵樹進(jìn)行一個(gè)深度優(yōu)先的遍歷,這樣每個(gè)節(jié)點(diǎn)都會有一個(gè)唯一的標(biāo)記,如下圖所示:
Virtual DOM 算法實(shí)現(xiàn)
Virtual DOM 算法得實(shí)現(xiàn)主要是用三個(gè)函數(shù):element,diff,patch。然后就可以實(shí)際的進(jìn)行使用,如下面代碼所示:
// 1. 構(gòu)建虛擬DOM var tree = el('div', {'id': 'container'}, [ el('h2', {style: 'color: blue'}, ['simple virtal dom']), el('p', ['Hello, virtual-dom']), el('ul', [el('li')]) ]) // 2. 通過虛擬DOM構(gòu)建真正的DOM var root = tree.render() document.body.appendChild(root) // 3. 生成新的虛擬DOM var newTree = el('div', {'id': 'container'}, [ el('h2', {style: 'color: red'}, ['simple virtal dom']), el('p', ['Hello, virtual-dom']), el('ul', [el('li'), el('li')]) ]) // 4. 比較兩棵虛擬DOM樹的不同 var patches = diff(tree, newTree) // 5. 在真正的DOM元素上應(yīng)用變更 patch(root, patches)
網(wǎng)頁題目:vue虛擬DOM的原理-創(chuàng)新互聯(lián)
網(wǎng)頁地址:http://aaarwkj.com/article10/dohego.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、標(biāo)簽優(yōu)化、用戶體驗(yàn)、營銷型網(wǎng)站建設(shè)、做網(wǎng)站、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容