react框架設計原理及生命週期
阿新 • • 發佈:2019-01-25
1、ReactJS的背景
1、react是Facebook為實現其內部廣告系統專案設計的一種前端介面構建方式
2、前端工程師的職責就是把邏輯資料實時反應到view層,既然涉及到vie層,
那就涉及到dom樹。而大家都知道,複雜或者頻繁的操作dom通常是造成效能
不好的地方。
3、所以設計react的地方就是其虛擬dom
2、ReactJS的設計原理
react的設計原理就是其引入的虛擬dom機制: 1、react用javascript在瀏覽器端實現了一套虛擬dom api。 2、基於react開發的時候所有的dom構造都是基於虛擬dom進行的 3、每當有state更改的時候,react就重新render一整套虛擬dom樹, react機制會將當前的整個dom樹和上一次的dom樹進行對比 取到diff,進行真實的dom更改。 4、其實state也有一部分實現的是資料、html片段繫結, 直接更新的資料是包含的
其實說到這裡,往深一點考慮就是react的虛擬dom的diff演算法
從大層面上來講
深層次一點就是react的diff演算法是怎麼理解的。
錯誤的見解:我曾經以為diff演算法,就是深層次的diff,演算法運算時只比較
不同的。但其實當時淺顯的想法,確實是diff運算的結果,但不是
diff運算的演算法。
1、tree diff
也叫層級diff,
針對上圖 React對Virtual DOM樹進行層級控制,只會對相同層級的DOM節點進行比 較,即同一個父元素下的所有子節點,當發現節點已經不存在了,則會刪除掉 該節點下所有的子節點,不會再進行比較。這樣只需要對DOM樹進行一次遍 歷,就可以完成整個樹的比較。 即使說a節點以及他的子節點被移動,但是react只關注同級比較,在第二層 把a及其子節點刪了,在第三層再重新建立,所以diff運算量大,影響效能 不建議setState直接更改樹的結構。最好是state顆粒度小,只改變樹中 的某一個小的節點,那麼diff的時候只會深度比較這一個小節點。
2、componnet diff
假如說因為某個條件切換,所以要顯示不同的元件。
1、比較兩個元件的型別(D和G)
2、如果(D和G)不是同一型別,進行diff演算法,分析會影響效能
直接刪掉上一個虛擬dom元件。 重新建立新的元件。
如果是同一型別的元件,會按照層級策略深層對比每個節點。
3、element diff 精確的對屬於同一層級的節點diff時,提供了3種節點操作,分別為INSERT_MARKUP(插入),MOVE_EXISTING(移動),REMOVE_NODE(刪除)。 如果同一層級,沒有這個新節點會新增插入 如果同一層級,如果有新節點,但是屬性不一樣,會複用節點,賦值屬性 如果同一層次,舊dom有,新dom沒有,會刪除這個節點。
總結:setState()觸發一次元件重繪,其實就是虛擬dom重新生成,除非在
shouldComponentUpdate()中實現了一些條件渲染邏輯。來允許和阻止是否需要
呼叫指定元件的 render 方法。其實這個深入邏輯就是他觸發了render,只是是
否觸發了內部的diff演算法,return false 的時候,不diff,render出來的新
舊dom一樣。diff演算法的複雜度為0。
React的核心
1、使用元件定義介面,是一個View層的前端庫,介面可能由
一個或者多個元件構建而成
react的虛擬DOM是如何反映到真實的DOM樹上的?
解答:首次渲染大量DOM時,由於多了一層虛擬DOM的計算,會比
innerHTML插入慢。虛擬DOM可以確保只對介面上真正變化的部分進行
實際的DOM操作。
比如:
替換節點就需要調原生JS物件的repaceChild()介面;
對於修改屬性,則要調setAttribute()介面等等。