【Under-the-hood-ReactJS-Part5】React源碼解讀

接上文,git

React流程圖:
https://bogdan-lyashenko.gith...github

更新DOM屬性

在更新DOM屬性這一步,主要的目標就是將以前的props和當前props的差別高效的更新到DOM上。下面是源碼裏的註釋:緩存

發現屬性差別後進行合併,而且在須要時進行DOM更新。這個方法極可能是性能優化的路徑上的最關鍵的單一方法。(「Reconciles the properties by detecting differences in property values and updating the DOM as necessary. This function is probably the single most critical path for performance optimization.」)

在這裏會進行兩次循環。第一次,遍歷上一次的props,而後再遍歷下一次的props。
在咱們的案例中,掛載時,lastProps(上一次的屬性)是空值(由於這是咱們第一次進行賦值),不過,咱們仍是能夠看看裏面發生了什麼性能優化

循環前props

在這個循環的第一步中,咱們會檢查nextProps是否包含相同的屬性值。若是有的話,對於這些屬性值咱們會先跳過,由於它們會在以後的nextprops循環中被處理掉。而後,咱們會重置樣式,刪除事件監聽器(若是以前有設置的話),移除DOM屬性和DOM屬性值。對於屬性的處理,咱們須要確保它們不是RESERVED_PROPS中的保留關鍵字,那些是真正的組件屬性,如children,dangerouslySetInnerHTML。dom

循環後props

在這個循環的第一步中,首先須要檢查prop是否改變了,也就是檢查屬性的下一個值是否和以前的不一樣。若是是相同的話,則什麼都不須要作。對於樣式(你應該發現對於樣式的處理有些特殊),若是根lastProp相比有變化的,React會更新其值。而後,添加會事件監聽器(就像onClick等等)。下面,咱們進一步的進行分析。ssh

注意,在整個React應用的運行過程當中,全部的事件都是經過名爲合成事件(synthetic events)的東西進行傳遞的。所謂的合成事件,就是爲了更高效的使React工做而組裝的一些包裝器。而管理事件的中介模塊就是就是EventPuginHub(srcrendererssharedstackeventEventPluginHub.js)。它包含了一個名爲listenerBank的map對象進行監聽器的緩存和光臨。咱們須要把咱們的事件監聽器加入其中,不過不是如今,而是在組件和DOM元素已經準備好處理事件的時候。在這裏,看起來好像咱們延遲了事件的執行,你能夠會問,咱們如何獲知事件發生的那一刻呢?不知道你是否還記得咱們會在全部的方法調用裏傳遞transaction這個事務對象,之因此這樣作,就是爲了讓咱們可以更方便的處理這種上面疑問的場景,看下代碼:svg

//src\renderers\dom\shared\ReactDOMComponent.js#222
transaction.getReactMountReady().enqueue(putListener, {
    inst: inst,
    registrationName: registrationName,
    listener: listener,
});

在處理完事件監聽器後,咱們須要設置DOM屬性和屬性值。就像上面說的那樣,咱們須要確保這些屬性不是RESEVED_PROPS的保留關鍵字,那些是真正的組件屬性,如children和djangerouslySetInnerHTML。性能

在處理屬性的先後差別過程當中,咱們會計算出styleUpdates的配置,而後把它傳遞給CSSPropertyOperations模塊。優化

如今,咱們已經完成對屬性更新的過程的分析,咱們能夠繼續下一步了。
(未完待續)code

相關文章
相關標籤/搜索