摘要:接上文完整流程圖見繼續我們的之旅,讓我們從的調用開始。他們就是用來表示組件方法的返回值,除此之外,沒有其他的。同時,在的創建期間,將會合并和如果有聲明的話,并且嚴重。顯然,這一步驟會引起一些性能問題。
接上文---
完整流程圖見:https://bogdan-lyashenko.gith...
繼續我們的React之旅,讓我們從ReactDOM.render的調用開始。
ReactDOM.render是我們分析的入口點。我們的應用從這里開始渲染內容到DOM樹中。為了方便調試,我們創建了一個
更多詳情請查看源碼 srcisomorphicclassicelementReactElement.js
在流程圖中,你可以發現有個叫做ReactMount的模塊。它包含了整個組件掛載的邏輯。
其實,ReactDOM中是沒有任何邏輯的,它不過是一個用來調用ReactMount的接口,所以當調用ReactDOM.render方法時,技術上來說,你真正調用的是ReactMount.render方法。那么整個掛載過程到底是怎么樣的呢?
Mounting is the process of initializing a React component by creating its representative DOM elements and inserting them into a supplied container.(掛載是指初始化一個React組件的過程,包括生成組件對應的DOM元素并插入指定的容器中)
以上文字來自于React代碼的注釋,那么這些到底是一個怎么樣的過程呢?我們先看下以下的一個轉化:
React需要將你組件里的JSX描述轉化為對應的HTML結構,并插入到DOM樹中,這個過程,
React需要處理所有的屬性,綁定的事件,內嵌的組件和所有邏輯。掛載,就是指把用高層次語言描述的組件(JSX)轉化為低層次的html代碼,然后插入到DOM樹中。
為了讓以上描述更具體下,考慮如下需求:
目標:確保滾動事件被監聽實例化React組件
在一個根組件的第一次渲染過程中,React會初始化滾動監聽事件,并且把滾動條相關數值緩存起來,這樣,當應用代碼可以在不觸發重排(reflow)的前提下,訪問到滾動條相關數據。由于不同的游覽器會有不同的實現,一些DOM的數值是非固定的,每次當你在代碼中獲取它們時,它們都有可能會重新計算。顯然,這一步驟會引起一些性能問題。比如,一些老的游覽器,是不支持pageX和pageY屬性的。為了解決這個問題,React會做一些優化,而這些優化過程中,可能就會需要很多其它技巧。在其它問題中,React為了解決某個具體的問題,都會用到很多技巧,滾動條就是一個具體的列子。
回顧下最開始的流程圖,這里有一個實例創建的過程。事實上,目前去創建一個
在JSX的轉化過程中,這里有三個階段。JSX轉化成React elements后,React elements會被轉化為以下內部React組件類型中的一:ReactCompositeComponent(開發自定義的組件),ReactDOMComponent(HTML DOM節點),ReactDOMTextComponent(文本節點)。我們先忽略ReactDOMTextComponent,重點放在前兩個。
什么是內部組件呢?你可能已經聽過虛擬DOM。虛擬DOM是一種DOM的表示方式,在React的diff差異計算以及其它過程中,使用虛擬DOM使得可以不直接DOM樹,而這恰是React性能不錯的原因之一。其實,在React的源碼中,并沒有什么文件或者類被稱作虛擬DOM,因為虛擬DOM只是一種概念,一種用來描述如何處理真實DOM的手段。有些人可能會說虛擬DOM表示的就是React elements,但是我不這么認為。在我看來,虛擬DOM指的是這三個類:ReactCompositeComponent,ReactDOMComponent,ReactDOMTextComponent。稍后我會詳細解釋原因。
讓我們繼續組件的實例化。我們會創建一個ReactCompositeComponent的實例,但是,
這個實例并不是因為我們將
//src enderersdomclientReactMount.js#277 TopLevelWrapper.prototype.render = function () { return this.props.child; };
根據以上代碼,很顯然只有一個TopLevelWrapper的實例被創建了,除此之外就沒有其它的了。在繼續下一步之前,我們看下以下內容:
DOM內嵌驗證
幾乎每次內嵌組件渲染時,它們都會被一個專門用來做HTML驗證的模塊--validateDOMNesting--來驗證結構是否合法。所謂的DOM內嵌驗證是指校驗子模塊和父模塊的標簽層次。比如,如果父組件的標簽是
閱讀 2888·2021-11-15 11:39
閱讀 1513·2021-08-19 10:56
閱讀 1093·2019-08-30 14:12
閱讀 3731·2019-08-29 17:29
閱讀 719·2019-08-29 16:21
閱讀 3418·2019-08-26 12:22
閱讀 1515·2019-08-23 16:30
閱讀 1015·2019-08-23 15:25