目錄
擴展學習資料
?Virtual DOM 是什么【虛擬dom】
React渲染
Virtual DOM VS 原生DOM【vDom是否比原生Dom更高效】
Virtual DOM數(shù)據(jù)結構
Virtaual DOM Diff【虛擬dom前后比對,更新不同dom的算法】
源碼解讀
react源碼組織方式:
React Stack Reconciler【react 棧 協(xié)調(diào)】
react v15.6.2 源碼
練習
擴展學習資料
名稱 |
鏈接 |
備注 |
Virtual DOM 定義 |
Virtual DOM and Internals – React |
英文 |
Virtual DOM Node |
Mithril.js |
英文 |
VDom與 DOM 的區(qū)別 |
The difference between Virtual DOM and DOM - React Kung Fu |
英文 |
React性能優(yōu)化:Virtual Dom原理淺析 |
[譯] React性能優(yōu)化:Virtual Dom原理淺析 - 掘金 |
|
[譯] Virtual Dom 和 Diff 算法 |
[譯] Virtual Dom 和 Diff 算法在 React 中是如何工作的? - 掘金 |
- 比較前一個的內(nèi)部實例與下一個內(nèi)部實例
- 更新內(nèi)部實例Virtual DOM(JavaScript對象) 中的組件樹結構。
- 僅更新存在實際變化的節(jié)點及其子節(jié)點的真實DOM。
?Virtual DOM 是什么【虛擬dom】
虛擬DOM(virtualdom,VDOM)是一個編程概念,將UI的“虛擬”表示形式保存在內(nèi)存中,并通過ReactDOM之類的庫渲染成“真實”的DOM,這個過程叫做協(xié)調(diào)。
virtual dom將UI節(jié)點抽象成js對象
UI節(jié)點抽象:Virtual Dom對HTML Dom的抽象
Learn Once,Write Anywhere:因為提供了對HTML DOM的抽象,所以在Web開發(fā)中,通常不需要去調(diào)用DOM API。也是因為抽象,所以React也可以開發(fā)Native(React Native)?!究缙脚_性】
Virtual Dom構建UI
構建UI:以我們經(jīng)常見的Web開發(fā)為例,來看下React是怎么通過Virtual DOM渲染成HTML元素的。
React渲染
class App extends Component {
state = {
text: 'Virtual DOM',
}
render() {
const {text} = this.state;
render (
<div>{text}</div>
)
}
}
通過Virtual DOM 渲染頁面
很簡單的例子,渲染state遍歷text的值。
可以看到React是通過render方法渲染Virtual DOM(這里不考慮優(yōu)化),從而繪制出真實DOM。意味著,每次修改了state的值就會執(zhí)行render方法。
Virtual DOM是HTML DOM的映射,基本結構大致是一樣的
?
Virtual DOM VS 原生DOM【vDom是否比原生Dom更高效】
- 原生DOM更新
- DOM API 調(diào)用更新UI
- Virtual DOM更新
- 每次render都會產(chǎn)生一份新的‘react dom’
- Virtual DOM要對新舊‘react dom’進行比較,從而確定在舊‘dom’的基礎上進行多少變更
- 確定最優(yōu)的變更策略之后調(diào)用DOM API更新UI
Virtual DOM渲染成HTML,在流程上會比原生DOM操作多幾個步驟
實際應用中,頁面的操作邏輯會比較復雜頻繁,多次頻繁操作Dom會導致頁面重繪,頁面重繪是影響頁面性能的關鍵指標,造成卡頓。react在內(nèi)部已經(jīng)做了考慮,所以說會比原生Dom更加高效
Virtual DOM數(shù)據(jù)結構
對UI節(jié)點抽象
在Virtual DOM中,對HTML節(jié)點進行抽象。用JS對象的形式表示HTML。
改變了過去對HTML節(jié)點的理解。
呈現(xiàn)在用戶面前的頁面就是一個復雜的遞歸對象。
const globaldom = {
tagName: 'html',
children: [
{
tagName: 'head',
}, {
tagName: 'body',
children: [{
tagName: 'div',
attributes: {
className: 'test'
}
}]
}
]
}
Virtaual DOM Diff【虛擬dom前后比對,更新不同dom的算法】
- Virtual DOM如何提高性能【高效更新】
- 我們將render產(chǎn)生的Virtual DOM簡稱‘Vdom’;
- 通常調(diào)用setState方法觸發(fā)Vdom更新;
- 通過對比新舊‘Vdom’,確定最優(yōu)實現(xiàn)新‘Vdom’所需的操作;
-
Virtual DOM Diff 的層次
- 組件級別比較
- 元素級別比較
HTML DOM是個完整的樹,常規(guī)樹遍歷的時間復雜度是n3,正是vdom對HTMLdom節(jié)點層次的劃分,使得HTML樹在Vdom中遍歷的時間復雜度降為n0這也是Vdom高效的原因之一。
Virtual DOM Diff是體現(xiàn)其性能/維護性的重要過程
- Component Diff【組件級比較】:不同就直接開始替換組件及它的子組件(不再比對子組件)
?
- 元素級別的比較【三個層面:創(chuàng)建、移動、刪除】
- 創(chuàng)建子節(jié)點
?react源碼:diff 添加子節(jié)點
createChild: function (child, afterNode, mountImage) {
return makeInsertMarkup(mountImage, afterNode, child._mountIndex);
},
- 刪除子節(jié)點
?react源碼:diff刪除子節(jié)點
removeChild: function (child, node) {
return makeRenove(child, node);
},
- 移動節(jié)點
?react源碼:diff移動子節(jié)點【截取片段】
// 老節(jié)點和新節(jié)點相等,說明是移動
if(prevChild === nextChild) {
updates = enqueue(updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex));
lastIndex = Math.max(prevChild._mountIndex, lastIndex);
prevChild._mountIndex = nextIndex;
}
moveChild: function (child, afterNode, toIndex, lastIndex) {
// 原節(jié)點所在的掛載順序數(shù) < 更新后所在的順序數(shù)
if (child._mountIndex < lastIndex) {
return makeMove(child, afterNode, toIndex);
} else {
// 不移動它,而是把它后面應該在前面的節(jié)點移動到它前面去
}
}
我們應該規(guī)避如圖示例,將最后一個節(jié)點移動到最前面。【這種操作顯得不那么高效】
react源碼比較復雜,不直觀【相對開發(fā)來說】;
react的移動、創(chuàng)建、刪除并不是在react包中實現(xiàn)的,而是在react dom這個包中實現(xiàn)的?!緞討B(tài)掛載技術】
?
源碼解讀
react源碼組織方式:
- 動態(tài)注入:react包源碼中只是聲明變量并沒有實現(xiàn),實現(xiàn)是寫在react dom包中【考慮到多平臺,把公共部分react抽了出來,react dom是個render器; react native是另一個render器;如公共方法setState,react中就只是定義;實現(xiàn)是在react dom、react native中實現(xiàn)各自的?!?/li>
- react dom中源碼:比如渲染HTML節(jié)點的時候,采用的是嵌套循環(huán)【渲染、更新、比較】(因為HTML樹本身就是一種循環(huán)嵌套的方式)
React Stack Reconciler【react 棧 協(xié)調(diào)】
render -> Virtual DOM Diff->commit【更新】
總結
1.Virtual DOM不僅僅是抽象了HTML Dom操作,更多的是抽象了UI節(jié)點,其次帶來一種編程理念:數(shù)據(jù)驅(qū)動視圖。
Virtual DOM本身的抽象性也使得跨平臺成為了可能。
2.如何看待VDom比原生Dom更加高效?
(1)高效的Diff算法實現(xiàn)更新
(2)可維護性和編程思維方面
react v15.6.2 源碼
練習
閱讀React源碼 ?React v15.6.2 重點閱讀 react-dom ReactMultiChild.js(react-dom/lib/ReactMultiChild.js) 源碼。文章來源:http://www.zghlxwxcb.cn/news/detail-677635.html
產(chǎn)出:文章來源地址http://www.zghlxwxcb.cn/news/detail-677635.html
- 一份 Virtual DOM 與 HTML DOM 的對比圖;
- 一份分析 Element 比較的流程圖。
到了這里,關于React原理 - React Virtual DOM 原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!